﻿// ....................................................................................................................
//	Author: Copyright (C) 2012 Ing. Marek Hubal
//	Email: hubal@acasoftware.org
// ....................................................................................................................

using System;

namespace core
{
    /// <summary>Trieda INodeList</summary>
    public class INodeList : IDisposable
    {
        /// <summary>Trieda IComputeOccupiedSpaceData</summary>
        public class IComputeOccupiedSpaceData
        {
            public long TotalSize;
            public int FilesCount;
            public int DirsCount;

            public string SourceDeviceRoot;
            public long SourceCapacity;
            public long SourceFreeSpace;
            public long SourceSpaceOccupied;
            public long SourceClusterSize;

            public string DestDeviceRoot;
            public long DestCapacity;
            public long DestFreeSpace;
            public long DestSpaceOccupied;
            public long DestClusterSize;

            /// <summary>Konstruktor</summary>
            public IComputeOccupiedSpaceData()
            {
                TotalSize = 0; FilesCount = DirsCount = 0;

                SourceDeviceRoot = null;
                SourceCapacity = 0;
                SourceFreeSpace = 0;
                SourceSpaceOccupied = 0;
                SourceClusterSize = -1;

                DestDeviceRoot = null;
                DestCapacity = 0;
                DestFreeSpace = 0;
                DestSpaceOccupied = 0;
                DestClusterSize = -1;
            }

            /// <summary>Prepocet</summary>
            /// <param name="pSize">velkost zaznamu</param>
            /// <param name="pClusterSize">velkost clustera</param>
            /// <returns>obsadena velkost</returns>
            protected long RecalcSize(long pSize, long pClusterSize)
            {
                if (pClusterSize == -1) return pSize; // Neplatny cluster?
                if (pSize == 0) return 0; // Nulova dlzka?

                ulong CS = (ulong)pClusterSize - 1; ulong S = (ulong)pSize;
                ulong U = (S & CS) == 0 ? S & (CS ^ 0xffffffffffffffff) : (S & (CS ^ 0xffffffffffffffff)) + (ulong)pClusterSize;
                return (long)U;
            }

            /// <summary>Zaradenie suboru</summary>
            /// <param name="pSize">velkost</param>
            public void AddFile(long pSize)
            {
                TotalSize += pSize;
                FilesCount++;
                SourceSpaceOccupied += RecalcSize(pSize, SourceClusterSize);
                DestSpaceOccupied += RecalcSize(pSize, DestClusterSize);
            }
            /// <summary>Zaradenie priecinku</summary>
            public void AddDir()
            {
                DirsCount++;
            }
        }

        /// <summary>Trieda IConfirmationFlags</summary>
        public class IConfirmationFlags
        {
            public const int DELETE_ERROR_RETRY = 0;
            public const int DELETE_ERROR_SKIP = 1;
            public const int DELETE_ERROR_SKIP_ALL = 2;
            public const int DELETE_READ_ONLY_YES = 0;
            public const int DELETE_READ_ONLY_YES_ALL = 1;
            public const int DELETE_READ_ONLY_SKIP = 2;
            public const int DELETE_READ_ONLY_SKIP_ALL = 3;
            public const int DELETE_SYSTEM_YES = 0;
            public const int DELETE_SYSTEM_YES_ALL = 1;
            public const int DELETE_SYSTEM_SKIP = 2;
            public const int DELETE_SYSTEM_SKIP_ALL = 3;
            public const int DELETE_NOT_EMPTY_FOLDER_YES = 0;
            public const int DELETE_NOT_EMPTY_FOLDER_YES_ALL = 1;
            public const int DELETE_NOT_EMPTY_FOLDER_SKIP = 2;
            public const int DELETE_NOT_EMPTY_FOLDER_SKIP_ALL = 3;
            public const int COPY_ERROR_RETRY = 0;
            public const int COPY_ERROR_SKIP = 1;
            public const int COPY_ERROR_SKIP_ALL = 2;
            public const int OPEN_SOURCE_ERROR_RETRY = 0;
            public const int OPEN_SOURCE_ERROR_SKIP = 1;
            public const int OPEN_SOURCE_ERROR_SKIP_ALL = 2;
            public const int OVERWRITE_DESTINATION_FILE_YES = 0;
            public const int OVERWRITE_DESTINATION_FILE_YES_ALL = 1;
            public const int OVERWRITE_DESTINATION_FILE_SKIP = 2;
            public const int OVERWRITE_DESTINATION_FILE_SKIP_ALL = 3;
            public const int CHECK_INTEGRITY_SOURCE_ERROR_SKIP = 0;
            public const int CHECK_INTEGRITY_SOURCE_ERROR_SKIP_ALL = 1;

            public int DeleteErrorFile; // Volba chyby mazania suboru
            public int DeleteReadOnlyFile; // Volba mazania read only suboru
            public int DeleteSystemFile; // Volba mazania hidden a system suboru
            public int DeleteNotEmptyFolder; // Volba mazania neprazdneho priecinku
            public int DeleteErrorFolder; // Volba chyby mazania priecinku
            public int CreateErrorFolder; // Volba chyby vytvorenia priecinku
            public int OpenSourceFileError; // Volba chyby otvorenia zdrojoveho suboru na citanie
            public int CreateDestinationFileError; // Volba chyby vytvorenia cieloveho suboru na zapis
            public int OverwriteDestinationFile; // Volba chyby prepisania cieloveho suboru
            public int OverwriteReadOnlyDestinationFile; // Volba chyby prepisania cieloveho suboru s atributom readonly
            public int OverwriteSystemDestinationFile; // Volba chyby prepisania cieloveho suboru s atributom system
            public int ReadSourceFileError; // Volba chyby citania zdrojoveho suboru
            public int WriteDestinationFileError; // Volba chyby zapisu do cieloveho suboru
            public int CheckIntegritySourceFileError; // Volba chyby kontroly integrity zdrojoveho suboru

            /// <summary>Konstruktor</summary>
            public IConfirmationFlags()
            {
                DeleteErrorFile = -1;
                DeleteReadOnlyFile = -1;
                DeleteSystemFile = -1;
                DeleteNotEmptyFolder = -1;
                DeleteErrorFolder = -1;
                CreateErrorFolder = -1;
                OpenSourceFileError = -1;
                CreateDestinationFileError = -1;
                OverwriteDestinationFile = -1;
                OverwriteReadOnlyDestinationFile = -1;
                OverwriteSystemDestinationFile = -1;
                ReadSourceFileError = -1;
                WriteDestinationFileError = -1;
                CheckIntegritySourceFileError = -1;
            }

            /// <summary>Property: ForceDeleteReadOnly</summary>
            public bool ForceDeleteReadOnly
            {
                get
                {
                    return (DeleteReadOnlyFile == DELETE_READ_ONLY_YES) || (DeleteReadOnlyFile == DELETE_READ_ONLY_YES_ALL);
                }
            }
            /// <summary>Property: ForceDeleteReadOnly</summary>
            public bool ForceDeleteSystem
            {
                get
                {
                    return (DeleteSystemFile == DELETE_SYSTEM_YES) || (DeleteSystemFile == DELETE_SYSTEM_YES_ALL);
                }
            }
            /// <summary>Property: ForceOverwriteDestinationFile</summary>
            public bool ForceOverwriteDestinationFile
            {
                get
                {
                    return (OverwriteDestinationFile == OVERWRITE_DESTINATION_FILE_YES) || (OverwriteDestinationFile == OVERWRITE_DESTINATION_FILE_YES_ALL);
                }
            }
            /// <summary>Property: ForceOverwriteReadOnlyDestinationFile</summary>
            public bool ForceOverwriteReadOnlyDestinationFile
            {
                get
                {
                    return (OverwriteReadOnlyDestinationFile == OVERWRITE_DESTINATION_FILE_YES) || (OverwriteReadOnlyDestinationFile == OVERWRITE_DESTINATION_FILE_YES_ALL);
                }
            }
            /// <summary>Property: ForceOverwriteSystemDestinationFile</summary>
            public bool ForceOverwriteSystemDestinationFile
            {
                get
                {
                    return (OverwriteSystemDestinationFile == OVERWRITE_DESTINATION_FILE_YES) || (OverwriteSystemDestinationFile == OVERWRITE_DESTINATION_FILE_YES_ALL);
                }
            }
        }

        public const int NODE_LIST_ID_NONE = 0;
        public const int NODE_LIST_ID_ROOT = 1;
        public const int NODE_LIST_ID_LOCAL_ITEMS = 2;
        public const int NODE_LIST_ID_SMB_NETWORK = 3;
        public const int NODE_LIST_ID_SMB_SHARES = 4;
        public const int NODE_LIST_ID_GZIP_ARCHIVE = 5;
        public const int NODE_LIST_ID_TAR_ARCHIVE = 6;
        public const int NODE_LIST_ID_RAR_ARCHIVE = 7;
        public const int NODE_LIST_ID_CLOUD_ROOT = 8;
        public const int NODE_LIST_ID_FTP = 9;
        public const int NODE_LIST_ID_ZIP_ARCHIVE = 10;
        public const int NODE_LIST_ID_VIRTUAL = 11;

        public const int MAX_COPY_BUFFER_SIZE = 32768;

        public int ID; // ID zoznamu
        public string LastError; // Posledna chyba
        public IThrSafeVariable WantExpandBreak; // Priznak ziadosti o prerusenie expandovania
        public IThrSafeVariable ProgressMessage; // Premenna pre text o priebehu
        public int ConnectionProvider; // ID poskytovatela spojenia
        public bool AskForCredentialsEnabled; // Priznak povolenia ziadat meno a heslo

        public int FilesCount, DirsCount, SelectedFilesCount, SelectedDirsCount; // Pocitadla
        public long FilesSize, DirsSize, SelectedFilesSize, SelectedDirsSize; // Sucet velkosti

        public IntPtr CopyMode_DataBuffer; // Buffer pre kopirovanie
        public byte[] CopyMode_NativeDataBuffer; // Buffer pre kopirovanie v nativnom mode

        protected int FColsCount; // Pocet stlpcov
        protected uint FDefVisibilityMask; // Prednastavena maska viditelnosti
        protected uint FEnableVisibilityMask; // Maska povolenia skryvania stlpcov
        protected IParamList FParams; // Parametre zoznamu
        protected uint FCurrentVisibilityMask; // Prednastavena maska viditelnosti
        protected bool FThreadExpandAvailable; // Priznak moznosti expandovania v threade
        protected System.Collections.Generic.List<INode> FItems; // Zoznam nodov
        protected System.IO.BinaryReader FCacheReader; // Reader pre cache
        protected System.IO.BinaryWriter FCacheWriter; // Writer pre cache
        protected bool FCachedContent; // Priznak pre nacitany obsah z cache
        protected bool FHasBackItem; // Priznak ci ma zoznam back polozku
        protected bool FFilteredContent; // Priznak filtrovaneho obsahu
        protected bool FWasChanged; // Priznak ci bol obsah zmeneny
        protected bool FSharedNodes; // Priznak zdielanych node objektov
        protected int FState; // Stav zoznamu

        protected System.Collections.Generic.Dictionary<string, int> FExtractMode_ItemsToExpandList; // Zoznam poloziek na spracovanie

        /// <summary>Property: CacheID</summary>
        public virtual string CacheID
        {
            get
            {
                return CurrentPath.ToLower();
            }
        }
        /// <summary>Property: PasswordCacheIDCacheID</summary>
        public virtual string PasswordCacheID
        {
            get
            {
                return CacheID;
            }
        }
        /// <summary>Otvorenie cache pre nacitanie</summary>
        /// <param name="pCacheID">ID cache</param>
        /// <returns>true / false</returns>
        protected virtual bool BeginReadCache(string pCacheID)
        {
            if (!IApp.GlobalData.FileExplorer_Cache.ContainsKey(pCacheID)) return false; // Nie je ziaden obsah v cache?

            try
            {
                string S = IApp.GlobalData.FileExplorer_Cache[pCacheID]; // Ziskam data
                FCacheReader = new System.IO.BinaryReader(S == "" ? new System.IO.MemoryStream() : new System.IO.MemoryStream(System.Convert.FromBase64String(S))); // Vytvorim stream
                FCacheReader.BaseStream.Position = 0;
            }
            catch
            {
                FCacheReader = null;
                return false;
            }

            return true;
        }
        /// <summary>Otvorenie cache pre zapis</summary>
        /// <param name="pCacheID">ID cache</param>
        /// <returns>true / false</returns>
        protected virtual bool BeginWriteCache(string pCacheID)
        {
            FCacheWriter = new System.IO.BinaryWriter(new System.IO.MemoryStream()); // Vytvorim stream
            return true;
        }
        /// <summary>Uzatvorenie cache</summary>
        protected virtual void EndWriteCache()
        {
            try
            {
                if (FCacheWriter == null) return; // Ziadna cache neotvorena
                FCacheWriter.BaseStream.Position = 0;
                string EncodedData = "";
                if (FCacheWriter.BaseStream.Length > 0) EncodedData = System.Convert.ToBase64String(((System.IO.MemoryStream)FCacheWriter.BaseStream).ToArray()); // Zakodujem obsah
                if (IApp.GlobalData.FileExplorer_Cache.ContainsKey(CacheID)) IApp.GlobalData.FileExplorer_Cache[CacheID] = EncodedData; // Ulozim do cache
                else IApp.GlobalData.FileExplorer_Cache.Add(CacheID, EncodedData);
            }
            catch
            {
                if (IApp.GlobalData.FileExplorer_Cache.ContainsKey(CacheID)) IApp.GlobalData.FileExplorer_Cache.Remove(CacheID); // Odstranim stary zaznam
            }

            FCacheWriter.Close();
            FCacheWriter = (System.IO.BinaryWriter)ICore.DisposeObject(FCacheWriter);
        }
        /// <summary>Uzatvorenie cache</summary>
        protected virtual void EndReadCache()
        {
            FCacheReader = (System.IO.BinaryReader)ICore.DisposeObject(FCacheReader);
        }
        /// <summary>Zapis node do cache</summary>
        /// <param name="pNode">objekt</param>
        protected virtual void WriteNodeToCache(INode pNode)
        {
        }
        /// <summary>Nacitanie node z cache</summary>
        /// <returns>objekt alebo null pre koniec</returns>
        protected virtual bool ReadNodeFromCache(INode Result)
        {
            return false;
        }
        /// <summary>Property: IsReadCacheReady</summary>
        protected virtual bool IsReadCacheReady
        {
            get
            {
                return FCacheReader != null;
            }
        }
        /// <summary>Property: IsWriteCacheReady</summary>
        protected virtual bool IsWriteCacheReady
        {
            get
            {
                return FCacheWriter != null;
            }
        }
        /// <summary>Otvorenie cache pre citanie</summary>
        /// <returns>true / false</returns>
        public virtual bool BeginReadCache()
        {
            return BeginReadCache(CacheID);
        }

        /// <summary>Property: ColsCount</summary>
        public int ColsCount
        {
            get
            {
                return FColsCount;
            }
        }
        /// <summary>Property: VisibleColsCount</summary>
        public int VisibleColsCount
        {
            get
            {
                return ICore.GetCount1(CurrentVisibilityMask);
            }
        }
        /// <summary>Property: CurrentVisibilityMask</summary>
        public uint CurrentVisibilityMask
        {
            get
            {
                if (FCurrentVisibilityMask == 0) FCurrentVisibilityMask = FParams.GetParam("VM", (uint)FDefVisibilityMask);
                return FCurrentVisibilityMask;
            }
            set
            {
                if (FCurrentVisibilityMask != value)
                {
                    FCurrentVisibilityMask = value;
                    FParams.SetParam("VM", value);
                }
            }
        }
        /// <summary>Property: NodesCount</summary>
        public int NodesCount
        {
            get
            {
                return FItems.Count;
            }
        }
        /// <summary>Property: []</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>objekt alebo null</returns>
        public INode this[int pIndex]
        {
            get
            {
                return ((pIndex < 0) || (pIndex >= FItems.Count)) ? null : FItems[pIndex];
            }
        }
        /// <summary>Property: SerializedParams</summary>
        public string SerializedParams
        {
            get
            {
                return FParams.Serialize(true);
            }
            set
            {
                FParams.Deserialize(value, true);
            }
        }
        /// <summary>Property: ThreadExpandAvailable</summary>
        public bool ThreadExpandAvailable
        {
            get
            {
                return FThreadExpandAvailable;
            }
        }
        /// <summary>Property: ItemsCount</summary>
        public int ItemsCount
        {
            get
            {
                return FilesCount + DirsCount;
            }
        }
        /// <summary>Property: SelectedItemsCount</summary>
        public int SelectedItemsCount
        {
            get
            {
                return SelectedFilesCount + SelectedDirsCount;
            }
        }
        /// <summary>Property: ItemsSize</summary>
        public long ItemsSize
        {
            get
            {
                return FilesSize + DirsSize;
            }
        }
        /// <summary>Property: SelectedItemsSize</summary>
        public long SelectedItemsSize
        {
            get
            {
                return SelectedFilesSize + SelectedDirsSize;
            }
        }
        /// <summary>Property: SelectedCount</summary>
        public int SelectedCount
        {
            get
            {
                return SelectedDirsCount + SelectedFilesCount;
            }
        }

        /// <summary>Konstruktor</summary>
        public INodeList()
        {
            // Inicializacia
            ID = NODE_LIST_ID_NONE;
            FColsCount = 0;
            FEnableVisibilityMask = 0x0; FDefVisibilityMask = 0xffffffff;
            FParams = new IParamList();
            FCurrentVisibilityMask = 0;
            FThreadExpandAvailable = true;
            FItems = new System.Collections.Generic.List<INode>();
            WantExpandBreak = new IThrSafeVariable();
            ProgressMessage = null;
            FCacheReader = null;
            FCacheWriter = null;
            FCachedContent = false;
            FHasBackItem = true;
            FFilteredContent = false;
            FWasChanged = false;
            FSharedNodes = false;
            FState = 0;
            ConnectionProvider = 0;
            CopyMode_DataBuffer = IntPtr.Zero;
            AskForCredentialsEnabled = false;
            ClearCounters(); // Inicializujem pocitadla
        }
        /// <summary>Dispose metoda</summary>
        public virtual void Dispose()
        {
            if (FParams == null) return; // Uz je objekt uvolneny?
            if (FState == 1) CloseExpand(); // Uzatvorim expand
            if (FState == 2) CloseCopyMode(); // Uzatvorim copy mode
            if (FState == 3) CloseCopyMode(); // Uzatvorim copy mode
            if (FState == 4) CloseExtractMode(); // Uzatvorim extract mode
            FParams = (IParamList)ICore.DisposeObject(FParams); // Uvolnim objekt
            Clear(); // Uvolnim zoznam
            FItems = null;
            WantExpandBreak = null;
            ProgressMessage = null;
            FCacheReader = (System.IO.BinaryReader)ICore.DisposeObject(FCacheReader);
            FCacheWriter = (System.IO.BinaryWriter)ICore.DisposeObject(FCacheWriter);
            GC.Collect();
        }

        /// <summary>Vymazanie obsahu zoznamu</summary>
        public virtual void Clear()
        {
            if (FItems == null) return; // Nealokovany zoznam?
            bool GCFree = FItems.Count > 10000; // Ziskam priznak volania uvolnenie garbage
            if (!FSharedNodes) // Ak nie su objekty zdielane...
            {
                for (int i = 0; i < FItems.Count; i++)
                {
                    FItems[i].Dispose(); // Zrusim kazdy node
                }
            }
            FItems.Clear(); // Zrusim obsah zoznamu
            if (GCFree) System.GC.Collect(); // Uvolnim garbage
        }
        /// <summary>Vymazanie pocitadiel</summary>
        public void ClearCounters()
        {
            FilesCount = DirsCount = SelectedFilesCount = SelectedDirsCount = 0;
            FilesSize = DirsSize = SelectedFilesSize = SelectedDirsSize = 0;
        }

        /// <summary>Ziskanie nazvu stlpca</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>nazov alebo prazdny retazec</returns>
        public virtual string GetColumnName(int pIndex)
        {
            return "";
        }
        /// <summary>Ziskanie nazvu viditelneho stlpca</summary>
        /// <param name="pIndex">logicka pozicia</param>
        /// <returns>nazov alebo prazdny retazec</returns>
        public string GetVisibleColumnName(int pIndex)
        {
            return GetColumnName(TranslateVisibilityIndex(pIndex)); // Volam prevod indexu a ziskanie nazvu
        }
        /// <summary>Ziskanie sirky stlpca</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>sirka</returns>
        public virtual int GetColumnWidth(int pIndex)
        {
            return FParams.GetParam(string.Format("CW{0}", pIndex), (int)150);
        }
        /// <summary>Ziskanie sirky viditelneho stlpca</summary>
        /// <param name="pIndex">logicky index</param>
        /// <returns>sirka stlpca</returns>
        public int GetVisibleColumnWidth(int pIndex)
        {
            return GetColumnWidth(TranslateVisibilityIndex(pIndex)); // Volam prevod indexu a ziskanie sirky stlpca
        }
        /// <summary>Nastavenie sirky stlpca</summary>
        /// <param name="pIndex">pozicia</param>
        /// <param name="pValue">hodnota</param>
        public void SetColumnWidth(int pIndex, int pValue)
        {
            FParams.SetParam(string.Format("CW{0}", pIndex), (int)pValue);
        }
        /// <summary>Nastavenie sirky viditelneho stlpca</summary>
        /// <param name="pIndex">logicka pozicia</param>
        /// <param name="pValue">hodnota</param>
        public void SetVisibleColumnWidth(int pIndex, int pValue)
        {
            SetColumnWidth(TranslateVisibilityIndex(pIndex), pValue); // Volam prevod indexu a nastavenie sirky
        }
        /// <summary>Ziskanie zarovnania stlpca</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>zarovnanie</returns>
        public virtual System.Windows.Forms.HorizontalAlignment GetColumnAlignment(int pIndex)
        {
            return System.Windows.Forms.HorizontalAlignment.Left;
        }
        /// <summary>Ziskanie zarovnania viditelneho stlpca</summary>
        /// <param name="pIndex">logicka pozicia</param>
        /// <returns>zarovnanie</returns>
        public System.Windows.Forms.HorizontalAlignment GetVisibleColumnAlignment(int pIndex)
        {
            return GetColumnAlignment(TranslateVisibilityIndex(pIndex)); // Volam prevod indexu a ziskanie zarovnania
        }
        /// <summary>Test ci sa node moze expandovat</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>true / false</returns>
        public virtual bool CanNodeExpand(int pIndex)
        {
            return false;
        }
        /// <summary>Test ci sa node moze otvorit</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>true / false</returns>
        public virtual bool CanNodeOpen(int pIndex)
        {
            return false;
        }
        /// <summary>Ziskanie expandovacej cesty node</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>cesta</returns>
        public virtual string GetNodeExpandPath(int pIndex)
        {
            return "";
        }
        /// <summary>Property: CurrentPath</summary>
        public virtual string CurrentPath
        {
            get
            {
                return "";
            }
        }
        /// <summary>Test ci sa node typu BACK_ITEM</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>true / false</returns>
        public virtual bool IsBackNode(int pIndex)
        {
            INode N = this[pIndex];
            return N == null ? false : N.ID == INode.NODE_ID_BACK_ITEM;
        }
        /// <summary>Property: CurrentPath</summary>
        public virtual string ParentPath
        {
            get
            {
                return IFileSystem.ExtractPath(CurrentPath);
            }
        }
        /// <summary>Property: KeyValue</summary>
        public virtual string KeyValue
        {
            get
            {
                return "";
            }
        }
        /// <summary>Ziskanie volneho miesta na zariadeni</summary>
        public virtual long DeviceFreeSpace
        {
            get
            {
                return -1;
            }
        }
        /// <summary>Property: DeviceRootPath</summary>
        public virtual string DeviceRootPath
        {
            get
            {
                return "";
            }
        }
        /// <summary>Test ci je mozne skryt stlpec</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>true / false</returns>
        public virtual bool CanHideColumn(int pIndex)
        {
            switch (pIndex)
            {
                case 0: return false;
                default: return true;
            }
        }
        /// <summary>Test ci je zadany stlpec viditelny</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>true / false</returns>
        public virtual bool IsColumnVisible(int pIndex)
        {
            uint M = CurrentVisibilityMask; // Aktualna maska viditelnosti
            uint M1 = 1; M1 <<= pIndex; // Bitova maska stlpca
            return (M & M1) != 0; // Vratim vyssledok testu
        }
        /// <summary>Nastavenie viditelnosti stlpca</summary>
        /// <param name="pIndex">pozicia</param>
        /// <param name="pValue">hodnota</param>
        public virtual void SetColumnVisibility(int pIndex, bool pValue)
        {
            if (!CanHideColumn(pIndex)) return; // Test pripustnosti
            uint M = CurrentVisibilityMask; // Aktualna maska viditelnosti
            uint M1 = 1; M1 <<= pIndex; // Bitova maska stlpca
            
            if (pValue) // Podla ziadosti budem maskovat
            {
                CurrentVisibilityMask |= M1;
            }
            else
            {
                M1 ^= 0xffffffff;
                CurrentVisibilityMask &= M1;
            }
        }
        /// <summary>Property: CanSort</summary>
        public virtual bool CanSort
        {
            get
            {
                return false;
            }
        }
        /// <summary>Test ci je mozne podla zadaneho stlpca triedit</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>true / false</returns>
        public virtual bool IsSortColumn(int pIndex)
        {
            return false;
        }
        /// <summary>Property: SortColumn</summary>
        public virtual int SortColumn
        {
            get
            {
                return FParams.GetParam("SC", (int)0);
            }
            set
            {
                FParams.SetParam("SC", value);
            }
        }
        /// <summary>Property: SortAsc</summary>
        public virtual bool SortAsc
        {
            get
            {
                return FParams.GetParam("SA", true);
            }
            set
            {
                FParams.SetParam("SA", value);
            }
        }
        /// <summary>Property: IsSlowDevice</summary>
        public virtual bool IsSlowDevice
        {
            get
            {
                return false;
            }
        }
        /// <summary>Ziskanie key. hodnoty pre podcestu zlava</summary>
        /// <param name="pDepth">hlbka</param>
        /// <returns>key. hodnota alebo prezdny retazec</returns>
        public virtual string GetSubKeyValue(int pDepth)
        {
            string P = IFileSystem.ExtractSubpath(CurrentPath, pDepth + 1);
            return P == "" ? "" : IFileSystem.ExtractName(P).ToLower();
        }
        /// <summary>Property: CachedContent</summary>
        public virtual bool CachedContent
        {
            get
            {
                return FCachedContent;
            }
        }
        /// <summary>Property: FilteredContent</summary>
        public virtual bool FilteredContent
        {
            get
            {
                return FFilteredContent;
            }
        }
        /// <summary>Property: CanSelect</summary>
        public virtual bool CanSelect
        {
            get
            {
                return false;
            }
        }
        /// <summary>Test moznosti oznacenia node</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>true / false</returns>
        public bool CanSelectNode(int pIndex)
        {
            return CanSelectNode(this[pIndex]);
        }
        /// <summary>Test moznosti oznacenia node</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>true / false</returns>
        public virtual bool CanSelectNode(INode pNode)
        {
            return false;
        }
        /// <summary>Ziskanie oznacenia node</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>true / false</returns>
        public virtual bool GetNodeSelection(int pIndex)
        {
            INode N = this[pIndex]; // Ziskam node
            return (N != null) && (N.Selected);
        }
        /// <summary>Property: WasChanged</summary>
        public virtual bool WasChanged
        {
            get
            {
                return FWasChanged;
            }
        }
        /// <summary>Property: CanShellCopy</summary>
        public virtual bool CanShellCopy
        {
            get 
            {
                return false;
            }
        }
        /// <summary>Property: CanShellPaste</summary>
        public virtual bool CanShellPaste
        {
            get 
            {
                return false;
            }
        }
        /// <summary>Property: CanShellCut</summary>
        public virtual bool CanShellCut
        {
            get
            {
                return false;
            }
        }
        /// <summary>Vytvorenie zakladnej tooltip informacie o node</summary>
        /// <param name="pNode">pozicia</param>
        /// <returns>vysledok</returns>
        public virtual string CreateBaseToolTipInfo(int pIndex)
        {
            return "";
        }
        /// <summary>Vytvorenie rozsirenej tooltip informacie o node</summary>
        /// <param name="pNode">pozicia</param>
        /// <returns>vysledok</returns>
        public virtual string CreateExtendedToolTipInfo(int pIndex)
        {
            return "";
        }
        /// <summary>Property: CanShellPrint</summary>
        public virtual bool CanShellPrint
        {
            get
            {
                return false;
            }
        }
        /// <summary>Ziskanie kapacity zariadenia</summary>
        public virtual long DeviceCapacity
        {
            get
            {
                return -1;
            }
        }
        /// <summary>Ziskanie velkosti klustera zariadenia</summary>
        public virtual int DeviceClusterSize
        {
            get
            {
                return -1;
            }
        }
        /// <summary>Property: CanCreateFolder</summary>
        public virtual bool CanCreateFolder
        {
            get
            {
                return false;
            }
        }
        /// <summary>Property: CanRename</summary>
        public virtual bool CanRename
        {
            get
            {
                return false;
            }
        }
        /// <summary>Test moznosti premenovania polozky</summary>
        public virtual bool CanRenameItem(int pIndex)
        {
            return false;
        }
        /// <summary>Property: IsCopySource</summary>
        public virtual bool IsCopySource
        {
            get
            {
                return false;
            }
        }
        /// <summary>Property: IsCopyDestination</summary>
        public virtual bool IsCopyDestination
        {
            get
            {
                return false;
            }
        }
        /// <summary>Property: IsCopySourceItem</summary>
        /// <param name="pIndex">pozicia</param>
        public virtual bool IsCopySourceItem(int pIndex)
        {
            return false;
        }
        /// <summary>Property: CanShellCopyItem</summary>
        /// <param name="pIndex">pozicia</param>
        public virtual bool CanShellCopyItem(int pIndex)
        {
            return false;
        }
        /// <summary>Property: CanTrash</summary>
        public virtual bool CanTrash
        {
            get
            {
                return false;
            }
        }
        /// <summary>Property: CanTrashItem</summary>
        /// <param name="pIndex">pozicia</param>
        public virtual bool CanTrashItem(int pIndex)
        {
            return false;
        }
        /// <summary>Property: IsMoveSource</summary>
        public virtual bool IsMoveSource
        {
            get
            {
                return false;
            }
        }
        /// <summary>Property: IsMoveSourceItem</summary>
        /// <param name="pIndex">pozicia</param>
        public virtual bool IsMoveSourceItem(int pIndex)
        {
            return false;
        }
        /// <summary>Property: CanShellCutItem</summary>
        /// <param name="pIndex">pozicia</param>
        public virtual bool CanShellCutItem(int pIndex)
        {
            return false;
        }
        /// <summary>Property: CanDelete</summary>
        public virtual bool CanDelete
        {
            get
            {
                return false;
            }
        }
        /// <summary>Property: CanDeleteItem</summary>
        /// <param name="pIndex">pozicia</param>
        public virtual bool CanDeleteItem(int pIndex)
        {
            return false;
        }
        /// <summary>Test ci node podporuje rychly presun poloziek na zadanu cestu</summary>
        /// <param name="pPath">cesta</param>
        /// <returns>true / false</returns>
        public virtual bool SupportFastMoveToPath(string pPath)
        {
            return false;
        }
        /// <summary>Test ci sa da node ako archiv extrahovat</summary>
        /// <param name="pIndex">pozicia node</param>
        /// <returns>true / false</returns>
        public virtual bool CanExtractArchiveNode(int pIndex)
        {
            return false;
        }
        /// <summary>Test ci sa da node ako archiv otestovat</summary>
        /// <param name="pIndex">pozicia node</param>
        /// <returns>true / false</returns>
        public virtual bool CanTestArchiveNode(int pIndex)
        {
            return false;
        }
        /// <summary>Property: Test ci je list archivom</summary>
        public virtual bool IsArchive
        {
            get
            {
                return false;
            }
        }
        /// <summary>Property: ArchiveName</summary>
        public virtual string ArchiveName
        {
            get
            {
                return "";
            }
        }
        /// <summary>Property: CanChangeAttributes</summary>
        public virtual bool CanChangeAttributes
        {
            get
            {
                return false;
            }
        }
        /// <summary>Test moznosti menit atributy node</summary>
        public virtual bool CanChangeAttributesNode(int pIndex)
        {
            return false;
        }
        /// <summary>Property: IsDragAndDropSource</summary>
        public virtual bool IsDragAndDropSource
        {
            get
            {
                return false;
            }
        }
        /// <summary>Property: SupportSearch</summary>
        public virtual bool SupportSearch
        {
            get
            {
                return false;
            }
        }
        /// <summary>Test moznosti vypoctu kontrolnych suctov</summary>
        public virtual bool CanCalcucateChecksum
        {
            get
            {
                return false;
            }
        }
        /// <summary>Test moznosti vypoctu kontrolnych suctov polozky</summary>
        public virtual bool CanCalcucateChecksumItem(int pIndex)
        {
            return false;
        }
        /// <summary>Test moznosti overenia kontrolnych suctov</summary>
        public virtual bool CanVerifyChecksum
        {
            get
            {
                return false;
            }
        }
        /// <summary>Test moznosti overenia kontrolnych suctov polozky</summary>
        public virtual bool CanVerifyChecksumItem(int pIndex)
        {
            return false;
        }
        /// <summary>Property: NeedPassword</summary>
        public virtual bool NeedPasswordForExpand
        {
            get
            {
                return false;
            }
        }
        /// <summary>Nastavenie hesla pre spracovanie</summary>
        /// <param name="pValue">hodnota</param>
        public virtual void SetPassword(string pValue)
        {
        }
        /// <summary>Ziskanie expandovacej cesty node</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>cesta</returns>
        public virtual int GetNodeConnectionProvider(int pIndex)
        {
            INode N = this[pIndex];
            return N == null ? 0 : N.ConnectionProvider;
        }
        /// <summary>Property: HasUnixAttributes</summary>
        public virtual bool HasUnixAttributes
        {
            get
            {
                return false;
            }
        }
        /// <summary>Property: BasePath</summary>
        public virtual string BasePath
        {
            get
            {
                return "";
            }
        }
        /// <summary>Property: CanBeViewed</summary>
        public virtual bool CanBeViewed
        {
            get
            {
                return false;
            }
        }
        /// <summary>Test ci moze byt node prezerany</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>true / false</returns>
        public virtual bool CanNodeBeViewed(int pIndex)
        {
            return false;
        }
        /// <summary>Test ci moze byt node editovany</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>true / false</returns>
        public virtual bool CanNodeBeEdited(int pIndex)
        {
            return false;
        }
        /// <summary>Property: CanMakeShortcut</summary>
        public virtual bool CanMakeShortcut
        {
            get
            {
                return false;
            }
        }
        /// <summary>Property: CanMakeShortcut</summary>
        public virtual bool CanNodeMakeShortcut(int pIndex)
        {
            return false;
        }
        /// <summary>Test ci zoznam moze obsluzit zadanu cestu</summary>
        /// <param name="pPath">cesta</param>
        /// <returns>true / false</returns>
        public virtual bool CanServerPath(string pPath)
        {
            return false;
        }
        /// <summary>Property: CanCloneFile</summary>
        public virtual bool CanCloneFile
        {
            get
            {
                return false;
            }
        }
        /// <summary>Property: IsSourceForArchive</summary>
        public virtual bool IsSourceForArchive
        {
            get
            {
                return false;
            }
        }
        /// <summary>Test ci je polozka zdrojom pre arechivaciu</summary>
        public virtual bool IsSourceForArchiveItem(int pIndex)
        {
            return false;
        }
        /// <summary>Property: IsSourceForArchive</summary>
        public virtual bool IsDestinationForArchive
        {
            get
            {
                return false;
            }
        }
        /// <summary>Property: IsEncryptionSource</summary>
        public virtual bool IsEncryptionSource
        {
            get
            {
                return false;
            }
        }
        /// <summary>Test ci je node source pre sifrovanie</summary>
        public virtual bool IsEncryptionSourceItem(int pIndex)
        {
            return false;
        }
        /// <summary>Property: IsEncryptionDestination</summary>
        public virtual bool IsEncryptionDestination
        {
            get
            {
                return false;
            }
        }
        /// <summary>Property: IsDecryptionSource</summary>
        public virtual bool IsDecryptionSource
        {
            get
            {
                return false;
            }
        }
        /// <summary>Test ci je node source pre desifrovanie</summary>
        public virtual bool IsDecryptionSourceItem(int pIndex)
        {
            return false;
        }
        /// <summary>Property: IsDecryptionDestination</summary>
        public virtual bool IsDecryptionDestination
        {
            get
            {
                return false;
            }
        }
        /// <summary>Property: CanCreateEmptyFile</summary>
        public virtual bool CanCreateEmptyFile
        {
            get
            {
                return false;
            }
        }
        /// <summary>Property: CanCreateFileFromClipboard</summary>
        public virtual bool CanCreateFileFromClipboard
        {
            get
            {
                return false;
            }
        }
        /// <summary>Test ci musi byt subor pre prezeranie skopirovany do temp priecinku</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>true / false</returns>
        public virtual bool NeedNodeToBeCopiedForView(int pIndex)
        {
            return false;
        }
        /// <summary>Property: IsCDDevice</summary>
        public virtual bool IsCDDevice
        {
            get
            {
                return IFileSystem.IsCDDevice(DeviceRootPath) == 1;
            }
        }
        /// <summary>Test ci je node CD zariadenim</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>true / false</returns>
        public virtual bool IsNodeCDDevice(int pIndex)
        {
            return false;
        }
        /// <summary>Property: CanRename</summary>
        public virtual bool CanMultiRename
        {
            get
            {
                return false;
            }
        }
        /// <summary>Test moznosti premenovania polozky</summary>
        public virtual bool CanMultiRenameItem(int pIndex)
        {
            return false;
        }

        /// <summary>Prevod logickej pozicie na fyzicku podla aktualnej masky viditelnosti stlpcov</summary>
        /// <param name="pIndex">logicka pozicia</param>
        /// <returns>fyzicka pozicia</returns>
        public int TranslateVisibilityIndex(int pIndex)
        {
            uint M = 0x1; // Maska
            uint VM = CurrentVisibilityMask; // Maska
            int C = 0; // Pocitadlo
            for (int i = 0; i < 32; i++) 
            {
                if ((M & VM) != 0) // Je zobrazeny stlpec?
                {
                    if (C == pIndex) return i;
                    C++;
                }
                M <<= 1;
            }
            return 0; // Mimo?
        }

        /// <summary>Zaciatok expandovania obsahu</summary>
        /// <param name="pFilter">objekt filtra</param>
        /// <returns>0 alebo kod chyby</returns>
        public virtual int BeginExpand(INodeFilters pFilter = null)
        {
            return 0;
        }
        /// <summary>Expandovanie dalsieho zaznamu</summary>
        /// <param name="pFilter">filter</param>
        /// <param name="Result">ulozeny obsah najdeneho zaznamu alebo null ak sa ma zaznam pripojit do zoznamu</param>
        /// <returns>0 - ziaden dalsi zaznam, 1 - najdeny zaznam alebo kod chyby</returns>
        public virtual int ExpandNext(INodeFilters pFilter = null, INode Result = null)
        {
            return 0;
        }
        /// <summary>Uzatvorenie aktualneho expandu</summary>
        public virtual void CloseExpand()
        {
        }
        /// <summary>Plny expand</summary>
        /// <param name="pFilter">objekt filtra</param>
        /// <param name="pReadFromCache">nacitanie obsahu z cache</param>
        /// <param name="pCanSaveToChache">moznost ulozenia obsahu do cache</param>
        /// <returns>0 alebo kod chyby</returns>
        public int FullExpand(INodeFilters pFilter = null, bool pReadFromCache = true, bool pCanSaveToChache = true)
        {
            LastError = ""; // Zmazem poslednu chybu

            WantExpandBreak.BoolValue = false;

            BeginWriteCache(CacheID);
            if (pReadFromCache) // Moze sa nacitat cache?
            {
                BeginReadCache(CacheID);
            }

            int R = BeginExpand(pFilter); // Inicializujem expandovanie
            if (R != 0) return R;

            while (true)
            {
                if (WantExpandBreak.BoolValue) break;
                R = ExpandNext(pFilter, null); // Dalsi zaznam
                if (R < 0) // Chyba?
                {
                    CloseExpand();
                    Clear();
                    return R;
                }
                if (R == 0) break;
            }
            CloseExpand(); // Ukoncim expandovanie

            if (pReadFromCache) // Moze sa nacitat cache?
            {
                EndReadCache();
            }

            EndWriteCache(); // Koniec cache

            return 0;
        }
        /// <summary>Zaradenie node do zoznamu</summary>
        /// <param name="pNode">objekt</param>
        /// <returns>pozicia</returns>
        public virtual int AddNode(INode pNode)
        {
            if (pNode.IsDirectory)
            {
                DirsCount++;
                if (pNode.ValidSize) DirsSize += pNode.Size;

            }

            if (pNode.IsFile)
            {
                FilesCount++;
                FilesSize += pNode.Size;
            }

            FItems.Add(pNode); // Zaradim do zoznamu
            return FItems.Count - 1;
        }
        /// <summary>Triedenie obsahu zoznamu</summary>
        /// <param name="pColumn">stlpec</param>
        /// <param name="pAsc">smer</param>
        public virtual void Sort(int pColumn, bool pAsc)
        {
        }
        /// <summary>Triedenie podla aktualneho nastavenia</summary>
        public void Sort()
        {
            if (!CanSort) return; // Test pripustnosti
            if (!IsSortColumn(SortColumn)) return;
            Sort(SortColumn, SortAsc); // Volam triedenie
        }
        /// <summary>Zmazanie node</summary>
        /// <param name="pIndex">pozicia</param>
        public virtual void DeleteNode(int pIndex)
        {
            INode N = this[pIndex]; // Ziskam node
            if (N == null) return;

            if (N.IsDirectory) // Je to priecinok?
            {
                DirsCount--;
                if (N.Selected) SelectedDirsCount--; // Je oznaceny?
                if (N.ValidSize) // Platna dlzka?
                {
                    DirsSize -= N.Size;
                    if (N.Selected) SelectedDirsSize -= N.Size; // Je oznaceny?
                }
            }

            if (N.IsFile) // Je to priecinok?
            {
                FilesCount--; FilesSize -= N.Size;
                if (N.Selected) // Je oznaceny?
                {
                    SelectedFilesCount--;
                    SelectedFilesSize -= N.Size;
                }
            }
            if (!FSharedNodes) N.Dispose(); // Zrusim node
            FItems.RemoveAt(pIndex); // Vymazem zo zoznamu
        }
        /// <summary>Filtrovanie obsahu</summary>
        /// <param name="pFilter">filter</param>
        /// <param name="Result">vysledny zoznam, v pripade null sa filtruje v aktualnom zoznamu</param>
        public virtual void FilterList(INodeFilters pFilter, INodeList Result = null)
        {
            if (Result != null)
            {
                Result.Clear(); Result.FSharedNodes = true;
                foreach (INode N in FItems)
                {
                    if (N.ID == INode.NODE_ID_BACK_ITEM) Result.AddNode(N);
                    else
                    {
                        if (pFilter.TestNode(N)) Result.AddNode(N);
                    }
                }
                return;
            }

            int C = FItems.Count - 1;
            for (int i = C; i >= 0; i--)
            {
                if (FItems[i].ID == INode.NODE_ID_BACK_ITEM) continue;
                if (!pFilter.TestNode(FItems[i])) DeleteNode(i);
            }
        }

        /// <summary>Vytvorenie textov pre zobrazenie</summary>
        /// <param name="pNode">objekt node</param>
        public virtual void CreateDisplayStrings(INode pNode)
        {
        }
        /// <summary>Vytvorenie textov pre zobrazenie</summary>
        /// <param name="pNode">pozicia</param>
        public void CreateDisplayStrings(int pIndex)
        {
            CreateDisplayStrings(this[pIndex]); // Volam vytvorenie
        }
        /// <summary>Zrusenie dat pre zobrazenie</summary>
        /// <param name="pIndex">index objektu alebo -1 pre vsetky</param>
        public virtual void DiscardDisplayData(int pIndex = -1)
        {
            if (pIndex != -1)
            {
                INode N = this[pIndex]; // Ziskam node
                if (N != null) // Je platny?
                {
                    N.DisplayStrings = null;
                    N.ImageIndex = -1;
                }
                return;
            }

            int C = FItems.Count;
            for (int i = 0; i < C; i++) // Prejdem vsetky node
            {
                INode N = FItems[i];
                N.DisplayStrings = null; // Zrusim data
                N.ImageIndex = -1;
            }
        }
        /// <summary>Najdenie pozicie node podla key. hodnoty</summary>
        /// <param name="pValue">hodnota</param>
        /// <returns>pozicia alebo -1</returns>
        public virtual int FindByKeyValue(string pValue)
        {
            int C = FItems.Count; // Pocet
            for (int i =0; i < C; i++) 
            {
                if (FItems[i].HasKeyValue(pValue)) return i;
            }
            return -1; // Nic som nenasiel
        }
        /// <summary>Hladanie pozicie node</summary>
        /// <param name="pValue">hodnota</param>
        /// <returns>pozicia alebo -1</returns>
        public virtual int FindPosition(INode pValue)
        {
            return FItems.IndexOf(pValue);
        }
        /// <summary>Nastavenie oznacenia zaznamu</summary>
        /// <param name="pIndex">pozicia</param>
        /// <param name="pValue">hodnota</param>
        public virtual void SelectItem(int pIndex, bool pValue)
        {
            if (!CanSelect) return; // Testy pripustnosti
            if (!CanSelectNode(pIndex)) return;

            INode N = this[pIndex]; // Ziskam node
            if (N == null) return; // Zly vstup?
            if (N.Selected == pValue) return; // Ziadna zmena?

            if (pValue) // Oznacenie?
            {
                if (N.IsDirectory) // Priecinok?
                {
                    SelectedDirsCount++;
                    if (N.ValidSize) SelectedDirsSize += N.Size;
                }
                if (N.IsFile) // Subor?
                {
                    SelectedFilesCount++;
                    SelectedFilesSize += N.Size;
                }
            }
            else // Odznacenie
            {
                if (N.IsDirectory) // Priecinok?
                {
                    SelectedDirsCount--;
                    if (N.ValidSize) SelectedDirsSize -= N.Size;
                }
                if (N.IsFile) // Subor?
                {
                    SelectedFilesCount--;
                    SelectedFilesSize -= N.Size;
                }
            }
            N.Selected = pValue; // Ulozim stav oznacenia
        }
        /// <summary>Oznacenie vsetkych zaznamov</summary>
        public virtual void SelectAllItems()
        {
            if (!CanSelect) return; // Testy pripustnosti

            foreach (INode N in FItems) // Prejdem cely zoznam 
            {
                if (!CanSelectNode(N)) continue; // Neda sa oznacit
                if (N.Selected) continue; // Uz je oznaceny?
                if (N.IsDirectory) // Priecinok?
                {
                    SelectedDirsCount++;
                    if (N.ValidSize) SelectedDirsSize += N.Size;
                }
                if (N.IsFile) // Subor?
                {
                    SelectedFilesCount++;
                    SelectedFilesSize += N.Size;
                }
                N.Selected = true;
            }
        }
        /// <summary>Odznacenie vsetkych zaznamov</summary>
        public virtual void DeSelectAllItems()
        {
            if (!CanSelect) return; // Testy pripustnosti

            foreach (INode N in FItems) // Prejdem cely zoznam 
            {
                if (!CanSelectNode(N)) continue; // Neda sa oznacit
                N.Selected = false;
            }
            SelectedDirsCount = 0; SelectedDirsSize = 0;
            SelectedFilesCount = 0; SelectedFilesSize = 0;
        }
        /// <summary>Zmena oznacenia vsetkych zaznamov</summary>
        public virtual void InvertSelectAllItems()
        {
            if (!CanSelect) return; // Testy pripustnosti

            foreach (INode N in FItems) // Prejdem cely zoznam 
            {
                if (!CanSelectNode(N)) continue; // Neda sa oznacit
                if (N.Selected)
                {
                    if (N.IsDirectory) // Priecinok?
                    {
                        SelectedDirsCount--;
                        if (N.ValidSize) SelectedDirsSize -= N.Size;
                    }
                    if (N.IsFile) // Subor?
                    {
                        SelectedFilesCount--;
                        SelectedFilesSize -= N.Size;
                    }
                }
                else
                {
                    if (N.IsDirectory) // Priecinok?
                    {
                        SelectedDirsCount++;
                        if (N.ValidSize) SelectedDirsSize += N.Size;
                    }
                    if (N.IsFile) // Subor?
                    {
                        SelectedFilesCount++;
                        SelectedFilesSize += N.Size;
                    }
                }
                N.Selected = !N.Selected;
            }
        }
        /// <summary>Oznacenie vsetkych priecinkov</summary>
        public virtual void SelectAllDirs()
        {
            if (!CanSelect) return; // Testy pripustnosti

            foreach (INode N in FItems) // Prejdem cely zoznam 
            {
                if (!CanSelectNode(N)) continue; // Neda sa oznacit
                if (N.Selected) continue; // Uz je oznaceny?
                if (!N.IsDirectory) continue; // Nie je priecinok?

                SelectedDirsCount++;
                if (N.ValidSize) SelectedDirsSize += N.Size;
                N.Selected = true;
            }
        }
        /// <summary>Odznacenie vsetkych priecinkov</summary>
        public virtual void DeSelectAllDirs()
        {
            if (!CanSelect) return; // Testy pripustnosti

            foreach (INode N in FItems) // Prejdem cely zoznam 
            {
                if (!CanSelectNode(N)) continue; // Neda sa oznacit
                if (!N.Selected) continue; // Uz je oznaceny?
                if (!N.IsDirectory) continue; // Nie je priecinok?

                SelectedDirsCount--;
                if (N.ValidSize) SelectedDirsSize -= N.Size;
                N.Selected = false;
            }
        }
        /// <summary>Odznacenie vsetkych priecinkov</summary>
        public virtual void InvertSelectAllDirs()
        {
            if (!CanSelect) return; // Testy pripustnosti

            foreach (INode N in FItems) // Prejdem cely zoznam 
            {
                if (!CanSelectNode(N)) continue; // Neda sa oznacit
                if (!N.IsDirectory) continue; // Nie je priecinok?

                if (N.Selected)
                {
                    SelectedDirsCount--;
                    if (N.ValidSize) SelectedDirsSize -= N.Size;
                }
                else
                {
                    SelectedDirsCount++;
                    if (N.ValidSize) SelectedDirsSize += N.Size;
                }
                N.Selected = !N.Selected;
            }
        }
        /// <summary>Oznacenie vsetkych suborov</summary>
        public virtual void SelectAllFiles()
        {
            if (!CanSelect) return; // Testy pripustnosti

            foreach (INode N in FItems) // Prejdem cely zoznam 
            {
                if (!CanSelectNode(N)) continue; // Neda sa oznacit
                if (N.Selected) continue; // Uz je oznaceny?
                if (!N.IsFile) continue; // Nie je priecinok?

                SelectedFilesCount++;
                SelectedFilesSize += N.Size;
                N.Selected = true;
            }
        }
        /// <summary>Odznacenie vsetkych suborov</summary>
        public virtual void DeSelectAllFiles()
        {
            if (!CanSelect) return; // Testy pripustnosti

            foreach (INode N in FItems) // Prejdem cely zoznam 
            {
                if (!CanSelectNode(N)) continue; // Neda sa oznacit
                if (!N.Selected) continue; // Uz je oznaceny?
                if (!N.IsFile) continue; // Nie je priecinok?

                SelectedFilesCount--;
                SelectedFilesSize -= N.Size;
                N.Selected = false;
            }
        }
        /// <summary>Odznacenie vsetkych suborov</summary>
        public virtual void InvertSelectAllFiles()
        {
            if (!CanSelect) return; // Testy pripustnosti

            foreach (INode N in FItems) // Prejdem cely zoznam 
            {
                if (!CanSelectNode(N)) continue; // Neda sa oznacit
                if (!N.IsFile) continue; // Nie je priecinok?

                if (N.Selected)
                {
                    SelectedFilesCount--;
                    SelectedFilesSize -= N.Size;
                }
                else
                {
                    SelectedFilesCount++;
                    SelectedFilesSize += N.Size;
                }
                N.Selected = !N.Selected;
            }
        }
        /// <summary>Ziskanie zoznamu nazvov oznacenych zaznamov</summary>
        /// <returns>zoznam</returns>
        public virtual System.Collections.Generic.List<string> GetListOfSelectedNames()
        {
            System.Collections.Generic.List<string> Result = new System.Collections.Generic.List<string>(); // Vytvorim zoznam
            foreach (INode N in FItems) // Prejdem cesly zoznam
            {
                if (!N.Selected) continue;
                string Name = N.Name;
                if (!string.IsNullOrEmpty(Name)) Result.Add(Name);
            }
            return Result; // Vratim vysledok
        }
        /// <summary>Ziskanie zoznamu plnych nazvov oznacenych zaznamov</summary>
        /// <returns>zoznam</returns>
        public virtual System.Collections.Generic.List<string> GetListOfSelectedFullNames()
        {
            string Path = CurrentPath;
            System.Collections.Generic.List<string> Result = new System.Collections.Generic.List<string>(); // Vytvorim zoznam
            foreach (INode N in FItems) // Prejdem cesly zoznam
            {
                if (!N.Selected) continue; // Nie je oznaceny?
                string Name = N.Name;
                if (!string.IsNullOrEmpty(Name)) Result.Add(IFileSystem.AppendToPath(Path, Name));
            }
            return Result; // Vratim vysledok
        }
        /// <summary>Ziskanie zoznamu plnych nazvov oznacenych zaznamov</summary>
        /// <returns>zoznam</returns>
        public virtual System.Collections.Generic.List<string> GetListOfSelectedFullNames_Files()
        {
            string Path = CurrentPath;
            System.Collections.Generic.List<string> Result = new System.Collections.Generic.List<string>(); // Vytvorim zoznam
            foreach (INode N in FItems) // Prejdem cesly zoznam
            {
                if (!N.Selected) continue; // Nie je oznaceny?
                if (!N.IsFile) continue; // Nie je subor?
                string Name = N.Name;
                if (!string.IsNullOrEmpty(Name)) Result.Add(IFileSystem.AppendToPath(Path, Name));
            }
            return Result; // Vratim vysledok
        }
        /// <summary>Ziskanie zoznamu nazvov oznacenych key. hodnot</summary>
        /// <returns>zoznam</returns>
        public virtual System.Collections.Generic.List<string> GetListOfSelectedKeyValues()
        {
            System.Collections.Generic.List<string> Result = new System.Collections.Generic.List<string>(); // Vytvorim zoznam
            foreach (INode N in FItems) // Prejdem cesly zoznam
            {
                if (!N.Selected) continue;
                string Name = N.KeyValue;
                if (!string.IsNullOrEmpty(Name)) Result.Add(Name);
            }
            return Result; // Vratim vysledok
        }
        /// <summary>Oznacenie zaznamov podla zoznamu key. hodnot</summary>
        /// <param name="pList">zoznam</param>
        public virtual void SelectItemsByKeyValues(System.Collections.Generic.List<string> pList)
        {
            if (!CanSelect) return; // Testy pripustnosti
            System.Collections.Generic.Dictionary<string, int> HashTable = ICore.StringList2DictionaryTable(pList); // Vytvorim hash tabulku

            foreach (INode N in FItems) // Prejdem cely zoznam 
            {
                if (!CanSelectNode(N)) continue; // Neda sa oznacit
                if (N.Selected) continue; // Uz je oznaceny?
                if (!HashTable.ContainsKey(N.KeyValue)) continue; // Nie je priecinok?

                if (N.IsDirectory) // Priecinok?
                {
                    SelectedDirsCount++;
                    if (N.ValidSize) SelectedDirsSize += N.Size;
                }
                if (N.IsFile) // Subor?
                {
                    SelectedFilesCount++;
                    SelectedFilesSize += N.Size;
                }

                N.Selected = true;
            }
            HashTable = null;
        }
        /// <summary>Odznacenie zaznamov podla zoznamu key. hodnot</summary>
        /// <param name="pList">zoznam</param>
        public virtual void DeSelectItemsByKeyValues(System.Collections.Generic.List<string> pList)
        {
            if (!CanSelect) return; // Testy pripustnosti
            System.Collections.Generic.Dictionary<string, int> HashTable = ICore.StringList2DictionaryTable(pList); // Vytvorim hash tabulku

            foreach (INode N in FItems) // Prejdem cely zoznam 
            {
                if (!CanSelectNode(N)) continue; // Neda sa oznacit
                if (!N.Selected) continue; // Uz je oznaceny?
                if (!HashTable.ContainsKey(N.KeyValue)) continue; // Nie je priecinok?

                if (N.IsDirectory) // Priecinok?
                {
                    SelectedDirsCount--;
                    if (N.ValidSize) SelectedDirsSize -= N.Size;
                }
                if (N.IsFile) // Subor?
                {
                    SelectedFilesCount--;
                    SelectedFilesSize -= N.Size;
                }

                N.Selected = false;
            }
            HashTable = null;
        }
        /// <summary>Ziskanie zoznamu key. hodnot zaznamov s rovnakym nazvom bez pripony</summary>
        /// <param name="pName">nazov bez pripony</param>
        /// <returns>zoznam</returns>
        public virtual System.Collections.Generic.List<string> GetListOfKeyValuesByNameOnly(string pName)
        {
            System.Collections.Generic.List<string> Result = new System.Collections.Generic.List<string>(); // Vytvorim zoznam
            foreach (INode N in FItems) // Prejdem cesly zoznam
            {
                string Name = N.NameOnly;
                if (!string.IsNullOrEmpty(Name))
                {
                    if (string.Compare(Name, pName, true) == 0) Result.Add(N.KeyValue);
                }
            }
            return Result; // Vratim vysledok
        }
        /// <summary>Ziskanie zoznamu key. hodnot zaznamov s rovnakou priponou</summary>
        /// <param name="pExt">pripona</param>
        /// <returns>zoznam</returns>
        public virtual System.Collections.Generic.List<string> GetListOfKeyValuesByExt(string pExt)
        {
            System.Collections.Generic.List<string> Result = new System.Collections.Generic.List<string>(); // Vytvorim zoznam
            foreach (INode N in FItems) // Prejdem cesly zoznam
            {
                string Ext = N.Ext;
                if (!string.IsNullOrEmpty(Ext))
                {
                    if (string.Compare(Ext, pExt, true) == 0) Result.Add(N.KeyValue);
                }
            }
            return Result; // Vratim vysledok
        }
        /// <summary>Ziskanie zoznamu nazvov vsetkych key. hodnot</summary>
        /// <returns>zoznam</returns>
        public virtual System.Collections.Generic.List<string> GetListOfKeyValues()
        {
            System.Collections.Generic.List<string> Result = new System.Collections.Generic.List<string>(); // Vytvorim zoznam
            foreach (INode N in FItems) // Prejdem cesly zoznam
            {
                string Name = N.KeyValue;
                if (!string.IsNullOrEmpty(Name)) Result.Add(Name);
            }
            return Result; // Vratim vysledok
        }
        /// <summary>Vymazanie oznacenych node</summary>
        public virtual void DeleteSelectedNodes()
        {
            int C = FItems.Count; // Ziskam pocet
            for (int i = C - 1; i >= 0; i--) // Prejdem zoznam
            {
                INode N = (INode)FItems[i];
                if (!N.Selected) continue;

                DeleteNode(i); // Vymazem
            }
        }
        /// <summary>Oznacenie vsetkych suborov</summary>
        /// <param name="pFilter">objekt filtra</param>
        public virtual void SelectItemsByFilter(INodeFilters pFilter)
        {
            if (!CanSelect) return; // Testy pripustnosti

            foreach (INode N in FItems) // Prejdem cely zoznam 
            {
                if (!CanSelectNode(N)) continue; // Neda sa oznacit
                if (N.Selected) continue; // Uz je oznaceny?

                if (!pFilter.TestNode(N)) continue; // Test filtra

                if (N.IsDirectory) // Priecinok?
                {
                    SelectedDirsCount++;
                    if (N.ValidSize) SelectedDirsSize += N.Size;
                }
                if (N.IsFile) // Subor?
                {
                    SelectedFilesCount++;
                    SelectedFilesSize += N.Size;
                }
                N.Selected = true;
            }
        }
        /// <summary>Spustenie dozerania na zmenu obsahu</summary>
        public virtual void StartChangedWatch()
        {
        }
        /// <summary>Zastavenie dozerania na zmenu obsahu</summary>
        public virtual void StopChangedWatch()
        {
        }
        /// <summary>Ziskanie key. hodnoty zadaneho node</summary>
        /// <param name="pIndex">pozicia</param>
        /// <returns>key. hodnota alebo prazdny retazec</returns>
        public virtual string GetNodeKeyValue(int pIndex)
        {
            INode N = this[pIndex];
            return N == null ? "" : N.KeyValue;
        }
        /// <summary>Ziskanie zoznamu plnych nazvov oznacenych zaznamov - archivov s podporou testu</summary>
        /// <returns>zoznam</returns>
        public virtual System.Collections.Generic.List<string> GetListOfSelectedFullNames_ArchivesSupportTest()
        {
            string Path = CurrentPath;
            System.Collections.Generic.List<string> Result = new System.Collections.Generic.List<string>(); // Vytvorim zoznam
            for (int i = 0; i < FItems.Count; i++) // Prejdem cesly zoznam
            {
                INode N = FItems[i];
                if (!N.Selected) continue; // Nie je oznaceny?
                if (!N.IsFile) continue; // Nie je subor?
                if (!CanTestArchiveNode(i)) continue;
                string Name = N.Name;
                if (!string.IsNullOrEmpty(Name)) Result.Add(IFileSystem.AppendToPath(Path, Name));
            }
            return Result; // Vratim vysledok
        }
        /// <summary>Ziskanie poctu oznacenych zaznamov - archivov s podporou testu</summary>
        /// <returns>pocet</returns>
        public virtual int GetCountOfSelectedFullNames_ArchivesSupportTest()
        {
            int C = 0;
            for (int i = 0; i < FItems.Count; i++) // Prejdem cesly zoznam
            {
                INode N = FItems[i];
                if (!N.Selected) continue; // Nie je oznaceny?
                if (!N.IsFile) continue; // Nie je subor?
                if (!CanTestArchiveNode(i)) continue;
                C++;
            }
            return C; // Vratim vysledok
        }
        /// <summary>Ziskanie zoznamu plnych nazvov oznacenych zaznamov - archivov s podporou extrahovania</summary>
        /// <returns>zoznam</returns>
        public virtual System.Collections.Generic.List<string> GetListOfSelectedFullNames_ArchivesSupportExtract()
        {
            string Path = CurrentPath;
            System.Collections.Generic.List<string> Result = new System.Collections.Generic.List<string>(); // Vytvorim zoznam
            for (int i = 0; i < FItems.Count; i++) // Prejdem cesly zoznam
            {
                INode N = FItems[i];
                if (!N.Selected) continue; // Nie je oznaceny?
                if (!N.IsFile) continue; // Nie je subor?
                if (!CanExtractArchiveNode(i)) continue;
                string Name = N.Name;
                if (!string.IsNullOrEmpty(Name)) Result.Add(IFileSystem.AppendToPath(Path, Name));
            }
            return Result; // Vratim vysledok
        }
        /// <summary>Ziskanie poctu oznacenych zaznamov - archivov s podporou extrahovania</summary>
        /// <returns>pocet</returns>
        public virtual int GetCountOfSelectedFullNames_ArchivesSupportExtract()
        {
            int C = 0;
            for (int i = 0; i < FItems.Count; i++) // Prejdem cesly zoznam
            {
                INode N = FItems[i];
                if (!N.Selected) continue; // Nie je oznaceny?
                if (!N.IsFile) continue; // Nie je subor?
                if (!CanExtractArchiveNode(i)) continue;
                C++;
            }
            return C; // Vratim vysledok
        }
        /// <summary>Ziskanie celkovej velkosti oznacenych zaznamov</summary>
        /// <returns>celkova velkost</returns>
        public virtual long GetTotalSizeOfSelectedFullNames_Files()
        {
            long Result = 0; // Vysledok

            string Path = CurrentPath;
            foreach (INode N in FItems) // Prejdem cesly zoznam
            {
                if (!N.Selected) continue; // Nie je oznaceny?
                if (!N.IsFile) continue; // Nie je subor?
                Result += N.Size;
            }
            return Result; // Vratim vysledok
        }

        /// <summary>Vytvorenie odkazu na zadany objekt</summary>
        /// <param name="pName">plny nazov</param>
        /// <param name="pSourceName">zdrojovy nazov</param>
        /// <returns>0 alebo kod chyby</returns>
        public virtual int CreateShortcut(string pName, string pSourceName)
        {
            return 0;
        }
        /// <summary>Premenovanie priecinku</summary>
        /// <param name="pName">nazov</param>
        /// <returns>0 alebo kod chyby</returns>
        public virtual int CreateFolder(string pName)
        {
            return 0;
        }
        /// <summary>Vytvorenie priecinku</summary>
        /// <param name="pCurrentName">aktualny nazov</param>
        /// <param name="pNewName">novy nazov</param>
        /// <returns>0 alebo kod chyby</returns>
        public virtual int RenameFolder(string pCurrentName, string pNewName)
        {
            return 0;
        }
        /// <summary>Premenovanie suboru</summary>
        /// <param name="pCurrentName">aktualny nazov</param>
        /// <param name="pNewName">novy nazov</param>
        /// <returns>0 alebo kod chyby</returns>
        public virtual int RenameFile(string pCurrentName, string pNewName)
        {
            return 0;
        }
        /// <summary>Ziskanie typu objektu</summary>
        /// <param name="pRelativeName">relativny nazov</param>
        /// <returns>OBJECT_TYPE_DIRECTORY, OBJECT_TYPE_FILE alebo kod chyby</returns>
        public virtual int GetItemType(string pRelativeName)
        {
            return IFileSystem.FS_ERROR_UNSUPPORTED;
        }
        /// <summary>Vytvorenie prazdneho suboru</summary>
        /// <param name="pName">nazov</param>
        /// <returns>0 alebo kod chyby</returns>
        public virtual int CreateEmptyFile(string pName)
        {
            return 0;
        }
        /// <summary>Vytvorenie klonu zoznamu</summary>
        /// <returns>objekt zoznamu</returns>
        public virtual INodeList CloneList()
        {
            return null;
        }

        /// <summary>Spustenie procesu kontroly archivu GZIP</summary>
        /// <param name="pErrorMsg">chybova sprava</param>
        /// <param name="pProgressForm">progress formular</param>
        /// <returns>true / false</returns>
        public virtual bool TestArchive(out string pErrorMsg, IFileExplorer_ProgressForm_TestArchive pProgressForm = null)
        {
            pErrorMsg = "";
            return true;
        }
        /// <summary>Ziskanie statistickych informacii pre proces extrahovania</summary>
        /// <param name="ResultStatData">vysledna stat. data</param>
        /// <param name="pItems">zoznam poloziek pre spocitanie</param>
        /// <param name="pBreakState">premenna pre oznamenie o preruseni spracovania</param>
        /// <returns>true / false</returns>
        public virtual bool Run_GetExtractStatsInfo(IComputeOccupiedSpaceData ResultStatData, System.Collections.Generic.List<string> pItems = null, IThrSafeVariable pBreakState = null)
        {
            return true; // Vsetko OK
        }

        /// <summary>Nastavenie zoznamu do modu zdroja kopirovania</summary>
        public virtual void BeginSourceCopyMode()
        {

        }
        /// <summary>Nastavenie zoznamu do modu ciela kopirovania</summary>
        public virtual void BeginDestinationCopyMode()
        {
        }
        /// <summary>Uzatvorenie modu kopirovania</summary>
        public virtual void CloseCopyMode()
        {
        }
        /// <summary>Vytvorenie relativnej cesty</summary>
        /// <param name="pPath">plna cesta</param>
        /// <param name="IsFolder">priznak ci to je priecinok</param>
        /// <param name="pProposal">navrh priznaku priecinku</param>
        /// <returns>relativna cesta</returns>
        public virtual string CopyMode_MakeRelative(string pPath, out bool IsFolder, bool pProposal = false)
        {
            IsFolder = false;
            return "";
        }
        /// <summary>Vytvorenie priecinku pri kopirovani</summary>
        /// <param name="pRelativePath">relativna cesta</param>
        /// <param name="pAttributes">atributy</param>
        /// <returns>0 alebo kod chyby</returns>
        public virtual int CopyMode_MakeFolder(string pRelativePath, uint pAttributes)
        {
            return 0;
        }
        /// <summary>Vymazanie priecinku</summary>
        /// <param name="pRelativePath">relativny nazov</param>
        /// <returns>0 alebo kod chyby</returns>
        public virtual int CopyMode_DeleteFolder(string pRelativePath)
        {
            return 0;
        }
        /// <summary>Vytvorenie zoznamu pre zdroj kopirovania</summary>
        /// <param name="pRelativePath">relativna cesta</param>
        /// <returns>zoznam</returns>
        public virtual INodeList CopyMode_CreateSourceList(string pRelativePath)
        {
            return null;
        }
        /// <summary>Vytvorenie plnej cesty</summary>
        /// <param name="pPath">relativna cesta</param>
        /// <returns>plna cesta</returns>
        public virtual string CopyMode_MakeDestinationFullPath(string pRelative)
        {
            return "";
        }
        /// <summary>Vytvorenie plnej cesty</summary>
        /// <param name="pPath">relativna cesta</param>
        /// <returns>plna cesta</returns>
        public virtual string CopyMode_MakeSourceFullPath(string pRelative)
        {
            return "";
        }

        /// <summary>Rychly presun priecinku</summary>
        /// <param name="pRelativeName">relativny nazov</param>
        /// <param name="pDestinationPath">cielova cesta</param>
        /// <returns>0 - OK alebo kod chyby</returns>
        public virtual int CopyMode_FastMoveFolder(string pRelativeName, string pDestinationPath)
        {
            return -1;
        }
        /// <summary>Rychly presun suboru</summary>
        /// <param name="pRelativeName">relativny nazov</param>
        /// <param name="pDestinationPath">cielova cesta</param>
        /// <returns>0 - OK alebo kod chyby</returns>
        public virtual int CopyMode_FastMoveFile(string pRelativeName, string pDestinationPath)
        {
            return -1;
        }

        /// <summary>Ziskanie atributov</summary>
        /// <param name="pRelativePath">relativna cesta</param>
        /// <returns>atributy</returns>
        public virtual uint CopyMode_GetAttributes(string pRelativePath)
        {
            return IWin32.INVALID_FILE_ATTRIBUTES;
        }
        /// <summary>Ziskanie datumu zmeny</summary>
        /// <param name="pRelativePath">relativna cesta</param>
        /// <returns>datum zmeny</returns>
        public virtual DateTime CopyMode_GetModifyDate(string pRelativePath)
        {
            return DateTime.MinValue;
        }
        /// <summary>Ziskanie dlzky</summary>
        /// <param name="pRelativePath">relativna cesta</param>
        /// <returns>dlzka</returns>
        public virtual long CopyMode_GetSize(string pRelativePath)
        {
            return -1;
        }
        /// <summary>Ziskanie datumu vytvorenia</summary>
        /// <param name="pRelativePath">relativna cesta</param>
        /// <returns>datum</returns>
        public virtual DateTime CopyMode_GetCreationDate(string pRelativePath)
        {
            return DateTime.MinValue;
        }
        /// <summary>Ziskanie datumu posledneho pristupu</summary>
        /// <param name="pRelativePath">relativna cesta</param>
        /// <returns>datum</returns>
        public virtual DateTime CopyMode_GetLastAccessDate(string pRelativePath)
        {
            return DateTime.MinValue;
        }

        /// <summary>Ziskanie atributov aktivneho suboru</summary>
        /// <returns>atributy</returns>
        public virtual uint CopyMode_GetAttributes()
        {
            return IWin32.INVALID_FILE_ATTRIBUTES;
        }
        /// <summary>Ziskanie datumu zmeny aktivneho suboru</summary>
        /// <returns>datum zmeny</returns>
        public virtual DateTime CopyMode_GetModifyDate()
        {
            return DateTime.MinValue;
        }
        /// <summary>Ziskanie dlzky aktivneho suboru</summary>
        /// <returns>dlzka</returns>
        public virtual long CopyMode_GetSize()
        {
            return -1;
        }

        /// <summary>Otvorenie suboroveho streamu</summary>
        /// <param name="pRelative">relativne meno</param>
        /// <param name="pInfo">informacie o subore</param>
        /// <returns>0 alebo kod chyby</returns>
        public virtual int CopyMode_OpenReadFile(string pRelative, INode pInfo = null)
        {
            return 0;
        }
        /// <summary>Uzatvorenie aktualne otvoreneho suboru pre citanie</summary>
        /// <param name="pDeleteAfterClose">priznak vymazania po uzatvoreni</param>
        public virtual void CopyMode_CloseReadFile(bool pDeleteAfterClose = false)
        {
        }
        /// <summary>Vytvorenie suboroveho streamu pre zapis</summary>
        /// <param name="pRelative">relativne meno</param>
        /// <param name="pAttributes">atributy noveho suboru</param>
        /// <param name="pCanOverwrite">priznak moznosti prepisania existujuceho suboru</param>
        /// <param name="pCanOverwriteAttr_ReadOnly">priznak moznosti prepisania existujuceho suboru s atributom readonly</param>
        /// <param name="pCanOverwriteAttr_Hidden">priznak moznosti prepisania existujuceho suboru s atributom hidden</param>
        /// <param name="pCanOverwriteAttr_System">priznak moznosti prepisania existujuceho suboru s atributom system</param>
        /// <param name="pModifyDate">datum modifikacie</param>
        /// <param name="pNativeStream">priznak pouzitia nativneho spracovania</param>
        /// <returns>0 alebo kod chyby</returns>
        public virtual int CopyMode_CreateWriteFile(string pRelative, uint pAttributes, DateTime pModifyDate, bool pCanOverwrite = false, bool pCanOverwriteAttr_ReadOnly = false, bool pCanOverwriteAttr_Hidden = false, bool pCanOverwriteAttr_System = false, bool pNativeStream = false)
        {
            return 0;
        }
        /// <summary>Uzatvorenie aktualne otvoreneho suboru pre zapis</summary>
        /// <param name="pDeleteAfterClose">priznak vymazania suboru po uzatvoreni</param>
        public virtual void CopyMode_CloseWriteFile(bool pDeleteAfterClose = false)
        {
        }
        /// <summary>Zapisanie retazca do textoveho suboru v ramci modu kopirovania</summary>
        /// <param name="pRelativeName">relativny nazov</param>
        /// <param name="pData">data suboru</param>
        /// <returns>0 alebo kod chyby</returns>
        public virtual int CopyMode_WriteTextFile(string pRelativeName, string pData)
        {
            return 0;
        }
        /// <summary>Nacitanie obsahu textoveho suboru</summary>
        /// <param name="pRelativeName">nazov</param>
        /// <param name="pMaxLength">max. dlzka alebo -1 pre cely obsah</param>
        /// <param name="Result">vysledok</param>
        /// <returns>0 alebo kod chyby</returns>
        public virtual int CopyMode_ReadFromTextFile(string pRelativeName, int pMaxLength, out string Result)
        {
            Result = "";
            return 0;
        }
        /// <summary>Vytvorenie streamu pre zapis</summary>
        /// <param name="pRelativeName">nazov</param>
        /// <param name="pCanOverwrite">priznak moznosti prepisania existujuceho suboru</param>
        /// <param name="pCanOverwriteAttr_ReadOnly">priznak moznosti prepisania existujuceho suboru s atributom readonly</param>
        /// <param name="pCanOverwriteAttr_Hidden">priznak moznosti prepisania existujuceho suboru s atributom hidden</param>
        /// <param name="pCanOverwriteAttr_System">priznak moznosti prepisania existujuceho suboru s atributom system</param>
        /// <returns>stream alebo null</returns>
        public virtual System.IO.Stream CopyMode_CreateStreamForWrite(string pRelativeName, out int pErrorCode, bool pCanOverwrite = false, bool pCanOverwriteAttr_ReadOnly = false, bool pCanOverwriteAttr_Hidden = false, bool pCanOverwriteAttr_System = false)
        {
            pErrorCode = IFileSystem.FS_ERROR_UNKNOWN;
            return null;
        }
        /// <summary>Uzatvorenie streamu pre zapis</summary>
        /// <param name="pStream">stream</param>
        /// <param name="pDeleteAfterClose">priznak vymazania po uzatvoreni</param>
        public virtual void CopyMode_CloseStreamForWrite(System.IO.Stream pStream, bool pDeleteAfterClose)
        {
        }
        /// <summary>Vytvorenie streamu pre zapis</summary>
        /// <param name="pRelativeName">nazov</param>
        /// <returns>stream alebo null</returns>
        public virtual System.IO.Stream CopyMode_OpenStreamForRead(string pRelativeName, out int pErrorCode)
        {
            pErrorCode = IFileSystem.FS_ERROR_UNKNOWN;
            return null;
        }
        /// <summary>Uzatvorenie streamu pre citanie</summary>
        /// <param name="pStream">stream</param>
        /// <param name="pDeleteAfterClose">priznak vymazania po uzatvoreni</param>
        public virtual void CopyMode_CloseStreamForRead(System.IO.Stream pStream, bool pDeleteAfterClose)
        {
        }

        /// <summary>Nacitanie obsahu</summary>
        /// <param name="pMaxLength">max. dlzka</param>
        /// <param name="pResultBuffer">vysledny buffer alebo null pre interny</param>
        /// <returns>pocet nacitanych bajtov alebo kod chyby</returns>
        public virtual int CopyMode_ReadFile(int pMaxLength, byte[] pResultBuffer)
        {
            return 0;
        }
        /// <summary>Zapisanie obsahu</summary>
        /// <param name="pBuffer">buffer</param>
        /// <param name="pStart">zaciatok</param>
        /// <param name="pLength">dlzka</param>
        /// <returns>pocet nacitanych bajtov alebo kod chyby</returns>
        public virtual int CopyMode_WriteFile(byte[] pBuffer, int pStart, int pLength)
        {
            return 0;
        }
        /// <summary>Nacitanie obsahu</summary>
        /// <param name="pMaxLength">max. dlzka</param>
        /// <param name="pResultBuffer">vysledny buffer alebo null pre interny</param>
        /// <returns>pocet nacitanych bajtov alebo kod chyby</returns>
        public virtual int CopyMode_ReadFile(int pMaxLength, IntPtr pResultBuffer)
        {
            return 0;
        }
        /// <summary>Zapisanie obsahu</summary>
        /// <param name="pBuffer">buffer</param>
        /// <param name="pStart">zaciatok</param>
        /// <param name="pLength">dlzka</param>
        /// <returns>pocet nacitanych bajtov alebo kod chyby</returns>
        public virtual int CopyMode_WriteFile(IntPtr pBuffer, int pStart, int pLength)
        {
            return 0;
        }
        /// <summary>Prerusenie aktualnej copy operacie</summary>
        public virtual void CopyMode_AbortOperation()
        {
        }

        /// <summary>Nastavenie zoznamu do modu zdroja extrahovania</summary>
        /// <param name="pItemsToExtract">polozky na extrahovanie</param>
        /// <param name="pProgressForm">progress formular</param>
        public virtual void BeginSourceExtractMode(System.Collections.Generic.List<string> pItemsToExtract = null, IFileExplorer_ProgressForm_ExtractArchive pProgressForm = null)
        {
        }
        /// <summary>Uzatvorenie modu extrahovania</summary>
        public virtual void CloseExtractMode()
        {
        }
        /// <summary>Ziskanie dalsieho zaznamu na extrahovanie</summary>
        /// <param name="Result">vysledne data</param>
        /// <returns>0 - koniec, 1 - platny zaznam, alebo kod chyby</returns>
        public virtual int ExtractMode_GetNextSourceItem(INode Result)
        {
            return 0;
        }
        /// <summary>Otvorenie aktualneho suboru na citanie</summary>
        /// <returns>0 alebo kod chyby</returns>
        public virtual int ExtractMode_OpenCurrentFileForRead()
        {
            return 0;
        }
        /// <summary>Uzatvorenie aktualneho suboru otvoreneho na citanie</summary>
        public virtual void ExtractMode_CloseReadFile()
        {
        }
        /// <summary>Preskocenie aktualneho zaznamu z extrahovania</summary>
        public virtual void ExtractMode_SkipCurrentItem()
        {
        }
        /// <summary>Test potreby extrahovania aktualneho zaznamu</summary>
        /// <returns>true / false</returns>
        public virtual bool ExtractMode_CurrentNeedExpand(ref string DestRelativePath)
        {
            return true;
        }
        /// <summary>Nacitanie obsahu</summary>
        /// <param name="pMaxLength">max. dlzka</param>
        /// <param name="pResultBuffer">vysledny buffer alebo null pre interny</param>
        /// <returns>pocet nacitanych bajtov alebo kod chyby</returns>
        public virtual int ExtractMode_ReadFile(int pMaxLength, byte[] pResultBuffer)
        {
            return 0;
        }
        /// <summary>Ziskanie nazvu aktualneho spracovavaneho zaznamu</summary>
        /// <returns>nazov</returns>
        public virtual string ExtractMode_CurrentName()
        {
            return "";
        }
        /// <summary>Test, ci zadany zaznam je poslednym na extrakciu</summary>
        /// <param name="pName">nazov</param>
        /// <param name="pIsDirectory">priznak priecinku</param>
        /// <returns>true / false</returns>
        public virtual bool ExtractMode_WasLastItemForExtract(string pName, bool pIsDirectory)
        {
            if (FExtractMode_ItemsToExpandList == null) return false;
            if (pIsDirectory) return false;
            if (FExtractMode_ItemsToExpandList.ContainsKey(pName.ToLower())) 
            {
                FExtractMode_ItemsToExpandList.Remove(pName.ToLower());
                return FExtractMode_ItemsToExpandList.Count == 0;
            }
            return false;
        }

        /// <summary>Spustenie mazania zaznamov</summary>
        /// <param name="pItems">zoznam objektov</param>
        /// <param name="pProgressForm">progress okno</param>
        /// <param name="pStatData">statisticke data pre vypocet stavu</param>
        public virtual bool Run_DeleteItems(System.Collections.Generic.List<string> pItems, IFileExplorer_ProgressForm_DeleteItems pProgressForm = null, IComputeOccupiedSpaceData pStatData = null)
        {
            return true;
        }
        /// <summary>Spustenie zmeny atributov zaznamov</summary>
        /// <param name="pChangeData">data pre zmenu</param>
        /// <param name="pItems">zoznam objektov</param>
        /// <param name="pProgressForm">progress okno</param>
        /// <param name="pStatData">statisticke data pre vypocet stavu</param>
        public virtual bool Run_ChangeItemsAttributes(IAttributeChangeDataObject pChangeData, System.Collections.Generic.List<string> pItems, IFileExplorer_ProgressForm_ChangeItemsAttributes pProgressForm = null, IComputeOccupiedSpaceData pStatData = null)
        {
            return true;
        }
        /// <summary>Spustenie hladania nad zoznamom</summary>
        /// <param name="pData">udaje pre hladanie</param>
        /// <param name="pProgressForm">progress formular</param>
        /// <returns>true / false</returns>
        public virtual bool Run_Search(ISearchDataStruct pData, int Depth, IFileExplorer_ProgressForm_Search pProgressForm = null)
        {
            return true;
        }
        /// <summary>Spustenie procesu klonovania suboru</summary>
        /// <param name="pName">nazov</param>
        /// <param name="pNewName">novy nazov</param>
        /// <param name="pProgressForm">progress formular</param>
        /// <returns>true / false</returns>
        public virtual bool Run_CloneFile(string pName, string pNewName, IFileExplorer_ProgressForm_CloneFile pProgressForm = null)
        {
            return true;
        }

        /// <summary>Spustenie procesu naplnenie virtualneho zoznamu obsahom priecinku a vsetkych podurovni</summary>
        /// <param name="Result">vysledok</param>
        /// <param name="pWantTerminate">priznak prerusenia</param>
        /// <returns>true / false</returns>
        public virtual bool Run_CreateVirtualList(INodeList_VirtualItems Result, IThrSafeVariable pWantTerminate = null)
        {
            using (INode N = new INode()) // Vytvorim node
            {
                if (BeginExpand() != 0) return true; // Zacnem expand
                while (true) // Prechadzam
                {
                    if ((pWantTerminate != null) && (pWantTerminate.BoolValue))
                    {
                        return false;
                    }

                    N.Clear();
                    if (ExpandNext(null, N) != 1) break; // Dalsi zaznam

                    string FullFN = IFileSystem.AppendToPath(CurrentPath, N.Name);
                    Result.AddNewNode(N, FullFN);
                    if (N.IsDirectory)
                    {
                        INodeList L = INodeList.CreateNodeList(FullFN);
                        if (L != null)
                        {
                            using (L)
                            {
                                if (!L.Run_CreateVirtualList(Result, pWantTerminate)) return false;
                            }
                        }
                    }
                }
                CloseExpand();
            }
            return true;
        }

        /// <summary>Spustenie procesu kopirovania</summary>
        /// <param name="pSourcePath">zdrojova cesta</param>
        /// <param name="pDestinationPath">cielova cesta</param>
        /// <param name="pItems">zoznam poloziek na kopirovania</param>
        /// <param name="pProgressForm">formular pre zobrazenie progresu</param>
        /// <param name="pStatData">statisticke data</param>
        /// <param name="pSourceConnectionProvider">zdrojovy poskytovatel spojenia</param>
        /// <param name="pDestinationConnectionProvider">cielovy poskytovatel spojenia</param>
        /// <returns>true / false</returns>
        public static bool Run_CopyItems(string pSourcePath, string pDestinationPath, System.Collections.Generic.List<string> pItems, IFileExplorer_ProgressForm_CopyItems pProgressForm = null, IComputeOccupiedSpaceData pStatData = null, int pSourceConnectionProvider = 0, int pDestinationConnectionProvider = 0)
        {
            IConfirmationFlags Flags = new IConfirmationFlags();

            INodeList SourceList = null;
            if (pSourcePath == "")
            {
                INodeList DestList = INodeList.CreateNodeList(pDestinationPath, pDestinationConnectionProvider);
                if (DestList == null) return false; // Chybna cielova cesta?
                using (DestList) 
                {
                    DestList.BeginDestinationCopyMode();
                    if (DestList.FState != 3) return false; // Nepodarila sa inicializacia?

                    foreach (string FN in pItems) // Prejdem kazdy zaznam
                    {
                        if (SourceList != null) // Je alokovany zdrojovy list?
                        {
                            if (string.Compare(IFileSystem.ExtractPath(FN), SourceList.CurrentPath, true) != 0) // Nie je rovnaky parent ako spracovana polozka?
                            {
                                SourceList.Dispose(); // Zrusim aktualny list
                                SourceList = null;
                            }
                        }
                        if (SourceList == null)
                        {
                            SourceList = INodeList.CreateNodeList(IFileSystem.ExtractPath(FN), pSourceConnectionProvider); // Vytvorim zoznam
                            if (SourceList == null) continue;

                            SourceList.BeginSourceCopyMode();
                            if (SourceList.FState != 2) return false; // Nepodarila sa inicializacia?
                        }

                        bool IsFolder;
                        string RelFN = SourceList.CopyMode_MakeRelative(FN, out IsFolder);
                        if (RelFN == "") continue;

                        if (IsFolder)
                        {
                            if (Run_CopyItems_Directory(SourceList, DestList, RelFN, Flags, pProgressForm) == -1) return false;
                        }
                        else
                        {
                            while (true)
                            {
                                int R = Run_CopyItems_File(SourceList, DestList, RelFN, Flags, pProgressForm);
                                if (R == -1) return false; // Prerusenie?
                                if (R != 2) break; // Neopakovat?
                            }
                        }
                    
                    }

                    if (SourceList != null) SourceList.Dispose(); 
                }
            }
            else
            {
                SourceList = INodeList.CreateNodeList(pSourcePath, pSourceConnectionProvider);
                if (SourceList == null) return false; // Chybna zdrojova cesta?
                using (SourceList)
                {
                    INodeList DestList = INodeList.CreateNodeList(pDestinationPath, pDestinationConnectionProvider);
                    if (DestList == null) return false; // Chybna cielova cesta?
                    using (DestList)
                    {
                        SourceList.BeginSourceCopyMode();
                        if (SourceList.FState != 2) return false; // Nepodarila sa inicializacia?

                        DestList.BeginDestinationCopyMode();
                        if (DestList.FState != 3) return false; // Nepodarila sa inicializacia?

                        bool IsFolder;
                        foreach (string FN in pItems)
                        {
                            string RelFN = SourceList.CopyMode_MakeRelative(FN, out IsFolder);
                            if (RelFN == "") continue;

                            if (IsFolder)
                            {
                                if (Run_CopyItems_Directory(SourceList, DestList, RelFN, Flags, pProgressForm) == -1) return false;
                            }
                            else
                            {
                                while (true)
                                {
                                    int R = Run_CopyItems_File(SourceList, DestList, RelFN, Flags, pProgressForm);
                                    if (R == -1) return false; // Prerusenie?
                                    if (R != 2) break; // Neopakovat?
                                }
                            }
                        }

                    }
                }
            }

            return true; // Vsetko OK
        }
        /// <summary>Skopirovanie priecinku</summary>
        /// <param name="pSource">zdroj</param>
        /// <param name="pDestination">ciel</param>
        /// <param name="pRelativeName">relativna cesta</param>
        /// <returns>0 - OK, 1 - preskocene, -1 prerusene</returns>
        protected static int Run_CopyItems_Directory(INodeList pSource, INodeList pDestination, string pRelativeName, IConfirmationFlags pFlags, IFileExplorer_ProgressForm_CopyItems pProgressForm = null)
        {
            if (pFlags.CreateErrorFolder != IConfirmationFlags.COPY_ERROR_SKIP_ALL) pFlags.CreateErrorFolder = -1; // Inicializujem potvrdenia

            while (true)
            {
                int R = pDestination.CopyMode_MakeFolder(pRelativeName, pSource.CopyMode_GetAttributes(pRelativeName));
                if ((R == 0) || (R == IFileSystem.FS_ERROR_DIRECTORY_EXISTS)) break;
                switch (R)
                {
                    default:
                        {
                            if (pFlags.CreateErrorFolder == IConfirmationFlags.COPY_ERROR_SKIP_ALL)
                            {
                                if (pProgressForm != null) pProgressForm.AddDir(true);
                                return 1; // Preskocit vsetky?
                            }

                            if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_20_4_1, pDestination.CopyMode_MakeDestinationFullPath(pRelativeName)), lang.FILE_EXPLORER_TEXT_20_4_2, lang.FILE_EXPLORER_TEXT_20_4_3, ref pFlags.CreateErrorFolder)) return -1;
                            switch (pFlags.CreateErrorFolder)
                            {
                                case IConfirmationFlags.COPY_ERROR_SKIP:
                                case IConfirmationFlags.COPY_ERROR_SKIP_ALL:
                                    {
                                        if (pProgressForm != null) pProgressForm.AddDir(true);
                                        return 1; // Preskocit?
                                    }
                            }
                        } break;
                }
            }

            if (pProgressForm != null) pProgressForm.AddDir();

            INodeList L = pSource.CopyMode_CreateSourceList(pRelativeName);
            if (L == null) return 1;

            bool IsFolder;
            using (INode N = new INode())
            {
                using (L)
                {
                    if (L.BeginExpand() == 0)
                    {
                        while (true)
                        {
                            N.Clear();
                            if (L.ExpandNext(null, N) != 1) break;

                            if (pProgressForm != null)
                            {
                                if (pProgressForm.WaitForTerminate.BoolValue) return -1; // Test ukoncenia
                            }

                            string RelFN = pSource.CopyMode_MakeRelative(IFileSystem.AppendToPath(L.CurrentPath, N.Name), out IsFolder, N.IsDirectory); // Ziskam relativnu cestu
                            if (RelFN != "") // Je platna?
                            {
                                if (IsFolder)
                                {
                                    if (Run_CopyItems_Directory(pSource, pDestination, RelFN, pFlags, pProgressForm) == -1) return -1;
                                }
                                else
                                {
                                    while (true)
                                    {
                                        int R = Run_CopyItems_File(pSource, pDestination, RelFN, pFlags, pProgressForm, N);
                                        if (R == -1) return -1; // Prerusenie
                                        if (R != 2) break; // Neopakovat?
                                    }
                                }
                            }
                        }
                        L.CloseExpand();
                    }
                }
            }

            return 0; // Vsetko OK
        }
        /// <summary>Skopirovanie suboru</summary>
        /// <param name="pSource">zdroj</param>
        /// <param name="pDestination">ciel</param>
        /// <param name="pRelativeName">relativna cesta</param>
        /// <returns>0 - OK, 1 - preskocene, -1 prerusene</returns>
        protected static int Run_CopyItems_File(INodeList pSource, INodeList pDestination, string pRelativeName, IConfirmationFlags pFlags, IFileExplorer_ProgressForm_CopyItems pProgressForm = null, INode pInfoNode = null)
        {
            if (pFlags.OpenSourceFileError != IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL) pFlags.OpenSourceFileError = -1; // Inicializacia
            if (pFlags.CreateDestinationFileError != IConfirmationFlags.COPY_ERROR_SKIP_ALL) pFlags.CreateDestinationFileError = -1;
            if ((pFlags.OverwriteDestinationFile != IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL) && (pFlags.OverwriteDestinationFile != IConfirmationFlags.OVERWRITE_DESTINATION_FILE_YES_ALL)) pFlags.OverwriteDestinationFile = -1;
            if ((pFlags.OverwriteReadOnlyDestinationFile != IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL) && (pFlags.OverwriteReadOnlyDestinationFile != IConfirmationFlags.OVERWRITE_DESTINATION_FILE_YES_ALL)) pFlags.OverwriteReadOnlyDestinationFile = -1;
            if ((pFlags.OverwriteSystemDestinationFile != IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL) && (pFlags.OverwriteSystemDestinationFile != IConfirmationFlags.OVERWRITE_DESTINATION_FILE_YES_ALL)) pFlags.OverwriteSystemDestinationFile = -1;
            if (pFlags.ReadSourceFileError != IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL) pFlags.ReadSourceFileError = -1;
            if (pFlags.WriteDestinationFileError != IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL) pFlags.WriteDestinationFileError = -1;

            while (true)
            {
                if (pProgressForm != null)
                {
                    if (pProgressForm.WaitForTerminate.BoolValue) return -1; // Test ukoncenia
                }

                int R = pSource.CopyMode_OpenReadFile(pRelativeName, pInfoNode); // Otvorim zdrojovy subor
                if (R == 0) break;
                switch (R)
                {
                    default:
                        {
                            if (pFlags.OpenSourceFileError == IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL)
                            {
                                if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                return 1; // Preskocit vsetky?
                            }

                            if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_20_4_4, pSource.CopyMode_MakeSourceFullPath(pRelativeName)), lang.FILE_EXPLORER_TEXT_20_4_5, lang.FILE_EXPLORER_TEXT_20_4_6, ref pFlags.OpenSourceFileError)) return -1;
                            switch (pFlags.OpenSourceFileError)
                            {
                                case IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP:
                                case IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL:
                                    {
                                        if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                        return 1; // Preskocit?
                                    }
                            }
                        } break;
                }
            }

            if (pProgressForm != null) pProgressForm.SetCurrentFileSize(pSource.CopyMode_GetSize(), IFileSystem.ExtractName(pSource.CopyMode_MakeSourceFullPath(pRelativeName)));
            while (true)
            {
                if (pProgressForm != null)
                {
                    if (pProgressForm.WaitForTerminate.BoolValue)
                    {
                        pSource.CopyMode_CloseReadFile();
                        return -1; // Test ukoncenia
                    }
                }

                int R = pDestination.CopyMode_CreateWriteFile(pRelativeName, pSource.CopyMode_GetAttributes(), pSource.CopyMode_GetModifyDate(), pFlags.ForceOverwriteDestinationFile, pFlags.ForceOverwriteReadOnlyDestinationFile, pFlags.ForceOverwriteSystemDestinationFile, pFlags.ForceOverwriteSystemDestinationFile); // Vytvorim cielovy subor
                if (R == 0) break; // OK..

                switch (R)
                {
                    case IFileSystem.FS_ERROR_FILE_EXISTS:
                        {
                            if (pFlags.OverwriteDestinationFile == IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL)
                            {
                                if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                pSource.CopyMode_CloseReadFile();
                                return 1;
                            }

                            if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_20_4_10, pDestination.CopyMode_MakeSourceFullPath(pRelativeName)), lang.FILE_EXPLORER_TEXT_20_4_11, lang.FILE_EXPLORER_TEXT_20_4_12, ref pFlags.OverwriteDestinationFile)) return -1;
                            switch (pFlags.OverwriteDestinationFile)
                            {
                                case IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP:
                                case IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL:
                                    {
                                        if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                        pSource.CopyMode_CloseReadFile();
                                        return 1;
                                    }
                            }

                        } break;
                    case IFileSystem.FS_ERROR_READ_ONLY_ATTRIBUTE:
                        {
                            if (pFlags.OverwriteReadOnlyDestinationFile == IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL)
                            {
                                if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                pSource.CopyMode_CloseReadFile();
                                return 1;
                            }
                            if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_20_4_13, pDestination.CopyMode_MakeSourceFullPath(pRelativeName)), lang.FILE_EXPLORER_TEXT_20_4_14, lang.FILE_EXPLORER_TEXT_20_4_15, ref pFlags.OverwriteReadOnlyDestinationFile)) return -1;
                            switch (pFlags.OverwriteReadOnlyDestinationFile)
                            {
                                case IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP:
                                case IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL:
                                    {
                                        if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                        pSource.CopyMode_CloseReadFile();
                                        return 1;
                                    }
                            }
                        } break;
                    case IFileSystem.FS_ERROR_SYSTEM_ATTRIBUTE:
                    case IFileSystem.FS_ERROR_HIDDEN_ATTRIBUTE:
                        {
                            if (pFlags.OverwriteSystemDestinationFile == IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL)
                            {
                                if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                pSource.CopyMode_CloseReadFile();
                                return 1;
                            }
                            if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_20_4_16, pDestination.CopyMode_MakeSourceFullPath(pRelativeName)), lang.FILE_EXPLORER_TEXT_20_4_17, lang.FILE_EXPLORER_TEXT_20_4_18, ref pFlags.OverwriteSystemDestinationFile)) return -1;
                            switch (pFlags.OverwriteSystemDestinationFile)
                            {
                                case IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP:
                                case IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL:
                                    {
                                        if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                        pSource.CopyMode_CloseReadFile();
                                        return 1;
                                    }
                            }
                        } break;
                    default:
                        {
                            if (pFlags.CreateDestinationFileError == IConfirmationFlags.COPY_ERROR_SKIP_ALL)
                            {
                                if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                pSource.CopyMode_CloseReadFile();
                                return 1; // Preskocit vsetky?
                            }
                            if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_20_4_7, pDestination.CopyMode_MakeSourceFullPath(pRelativeName)), lang.FILE_EXPLORER_TEXT_20_4_8, lang.FILE_EXPLORER_TEXT_20_4_9, ref pFlags.CreateDestinationFileError)) return -1;
                            switch (pFlags.CreateDestinationFileError)
                            {
                                case IConfirmationFlags.COPY_ERROR_SKIP:
                                case IConfirmationFlags.COPY_ERROR_SKIP_ALL:
                                    {
                                        pSource.CopyMode_CloseReadFile();
                                        if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                        return 1; // Preskocit vsetky?
                                    }
                            }
                        } break;
                }
            }

            while (true)
            {
                if (pProgressForm != null)
                {
                    if (pProgressForm.WaitForTerminate.BoolValue)
                    {
                        pSource.CopyMode_AbortOperation(); pDestination.CopyMode_AbortOperation(); // Prerusim operacie
                        if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                        pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                        pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                        if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                        return -1; // Test ukoncenia
                    }
                }


                int C = pSource.CopyMode_ReadFile(MAX_COPY_BUFFER_SIZE, pSource.CopyMode_DataBuffer); // Citam
                if (C == 0) break; // Koniec
                if (C < 0)
                {
                    if (pFlags.ReadSourceFileError == IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL) // Preskocim?
                    {
                        pSource.CopyMode_AbortOperation(); pDestination.CopyMode_AbortOperation(); // Prerusim operacie
                        if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                        pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                        pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                        if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                        return 1;
                    }
                    if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_20_4_19, pSource.CopyMode_MakeSourceFullPath(pRelativeName)), lang.FILE_EXPLORER_TEXT_20_4_20, lang.FILE_EXPLORER_TEXT_20_4_21, ref pFlags.ReadSourceFileError))
                    {
                        pSource.CopyMode_AbortOperation(); pDestination.CopyMode_AbortOperation(); // Prerusim operacie
                        if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                        pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                        pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                        if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                        return -1; // Prerusenie
                    }
                    switch (pFlags.ReadSourceFileError)
                    {
                        case IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP:
                        case IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL:
                            {
                                pSource.CopyMode_AbortOperation(); pDestination.CopyMode_AbortOperation(); // Prerusim operacie
                                if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                                pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                                pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                                if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                return 1;
                            }
                    }
                    continue;
                }


                while (true)
                {
                    if (pProgressForm != null)
                    {
                        if (pProgressForm.WaitForTerminate.BoolValue)
                        {
                            pSource.CopyMode_AbortOperation(); pDestination.CopyMode_AbortOperation(); // Prerusim operacie
                            if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                            pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                            pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                            if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                            return -1; // Prerusenie
                        }
                    }

                    int R = pDestination.CopyMode_WriteFile(pSource.CopyMode_DataBuffer, 0, C); // Zapisem
                    if (R == 0) break;
                    switch (R)
                    {
                        case IFileSystem.FS_ERROR_NOT_ENOUGH_SPACE: // Plny disk?
                            {
                                R = 0;
                                if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_20_4_25, pDestination.CopyMode_MakeSourceFullPath(pRelativeName)), lang.FILE_EXPLORER_TEXT_20_4_26, lang.FILE_EXPLORER_TEXT_20_4_27, ref R))
                                {
                                    pSource.CopyMode_AbortOperation(); pDestination.CopyMode_AbortOperation(); // Prerusim operacie
                                    if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                                    pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                                    pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                                    if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                    return -1; // Test ukoncenia
                                }
                                pSource.CopyMode_AbortOperation(); pDestination.CopyMode_AbortOperation(); // Prerusim operacie
                                if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                                pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                                pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                                return 2; // Opakovat operaciu
                            }
                        default:
                            {
                                if (pFlags.WriteDestinationFileError == IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL) // Preskocim?
                                {
                                    pSource.CopyMode_AbortOperation(); pDestination.CopyMode_AbortOperation(); // Prerusim operacie
                                    if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                                    pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                                    pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                                    if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                    return 1;
                                }
                                if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_20_4_22, pDestination.CopyMode_MakeSourceFullPath(pRelativeName)), lang.FILE_EXPLORER_TEXT_20_4_23, lang.FILE_EXPLORER_TEXT_20_4_24, ref pFlags.WriteDestinationFileError))
                                {
                                    pSource.CopyMode_AbortOperation(); pDestination.CopyMode_AbortOperation(); // Prerusim operacie
                                    if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                                    pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                                    pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                                    if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                    return -1; // Test ukoncenia
                                }

                                switch (pFlags.WriteDestinationFileError)
                                {
                                    case IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP:
                                    case IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL:
                                        {
                                            pSource.CopyMode_AbortOperation(); pDestination.CopyMode_AbortOperation(); // Prerusim operacie
                                            if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                                            pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                                            pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                                            if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                            return 1;
                                        }
                                }
                            } break;
                    }

                }

                if (pProgressForm != null) pProgressForm.AddTransferredDataSize(C); // Zaradim data
            }

            if (pProgressForm != null) pProgressForm.AddTransferredDataSize(0); // Koniec prenosu

            pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
            pDestination.CopyMode_CloseWriteFile(false); // Uzatvorim subor
            if (pProgressForm != null) pProgressForm.AddFile(); // Zaradim subor
            return 0; // Vsetko OK
        }

        /// <summary>Spustenie procesu presunu</summary>
        /// <param name="pSourcePath">zdrojova cesta</param>
        /// <param name="pDestinationPath">cielova cesta</param>
        /// <param name="pItems">zoznam poloziek na kopirovania</param>
        /// <param name="pProgressForm">formular pre zobrazenie progresu</param>
        /// <param name="pStatData">statisticke data</param>
        /// <param name="pSourceConnectionProvider">zdrojovy poskytovatel spojenia</param>
        /// <param name="pDestinationConnectionProvider">cielovy poskytovatel spojenia</param>
        /// <returns>true / false</returns>
        public static bool Run_MoveItems(string pSourcePath, string pDestinationPath, System.Collections.Generic.List<string> pItems, IFileExplorer_ProgressForm_MoveItems pProgressForm = null, IComputeOccupiedSpaceData pStatData = null, int pSourceConnectionProvider = 0, int pDestinationConnectionProvider = 0)
        {
            IConfirmationFlags Flags = new IConfirmationFlags();

            INodeList SourceList = INodeList.CreateNodeList(pSourcePath, pSourceConnectionProvider);
            if (SourceList == null) return false; // Chybna zdrojova cesta?
            using (SourceList)
            {
                INodeList DestList = INodeList.CreateNodeList(pDestinationPath, pDestinationConnectionProvider);
                if (DestList == null) return false; // Chybna cielova cesta?
                using (DestList)
                {
                    SourceList.BeginSourceCopyMode();
                    if (SourceList.FState != 2) return false; // Nepodarila sa inicializacia?

                    DestList.BeginDestinationCopyMode();
                    if (DestList.FState != 3) return false; // Nepodarila sa inicializacia?

                    bool IsFolder;
                    foreach (string FN in pItems)
                    {
                        string RelFN = SourceList.CopyMode_MakeRelative(FN, out IsFolder);
                        if (RelFN == "") continue;

                        if (IsFolder)
                        {
                            if (Run_MoveItems_Directory(SourceList, DestList, RelFN, Flags, pProgressForm) == -1) return false;
                        }
                        else
                        {
                            while (true)
                            {
                                int R = Run_MoveItems_File(SourceList, DestList, RelFN, Flags, pProgressForm);
                                if (R == -1) return false; // Prerusit?
                                if (R != 2) break; // Neopakovat?
                            }
                        }
                    }
                }
            }

            return true; // Vsetko OK
        }
        /// <summary>Presun priecinku</summary>
        /// <param name="pSource">zdroj</param>
        /// <param name="pDestination">ciel</param>
        /// <param name="pRelativeName">relativna cesta</param>
        /// <returns>0 - OK, 1 - preskocene, -1 prerusene</returns>
        protected static int Run_MoveItems_Directory(INodeList pSource, INodeList pDestination, string pRelativeName, IConfirmationFlags pFlags, IFileExplorer_ProgressForm_MoveItems pProgressForm = null)
        {
            // Pokusim sa o rychly presun
            if (pSource.CopyMode_FastMoveFolder(pRelativeName, pDestination.CopyMode_MakeDestinationFullPath(pRelativeName)) == 0)
            {
                if (pProgressForm != null) pProgressForm.AddDir();
                return 0;
            }

            if (pFlags.CreateErrorFolder != IConfirmationFlags.COPY_ERROR_SKIP_ALL) pFlags.CreateErrorFolder = -1; // Inicializujem potvrdenia

            while (true)
            {
                int R = pDestination.CopyMode_MakeFolder(pRelativeName, pSource.CopyMode_GetAttributes(pRelativeName));
                if ((R == 0) || (R == IFileSystem.FS_ERROR_DIRECTORY_EXISTS)) break;
                switch (R)
                {
                    default:
                        {
                            if (pFlags.CreateErrorFolder == IConfirmationFlags.COPY_ERROR_SKIP_ALL)
                            {
                                if (pProgressForm != null) pProgressForm.AddDir(true);
                                return 1; // Preskocit vsetky?
                            }

                            if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_21_4_1, pDestination.CopyMode_MakeDestinationFullPath(pRelativeName)), lang.FILE_EXPLORER_TEXT_21_4_2, lang.FILE_EXPLORER_TEXT_21_4_3, ref pFlags.CreateErrorFolder)) return -1;
                            switch (pFlags.CreateErrorFolder)
                            {
                                case IConfirmationFlags.COPY_ERROR_SKIP:
                                case IConfirmationFlags.COPY_ERROR_SKIP_ALL:
                                    {
                                        if (pProgressForm != null) pProgressForm.AddDir(true);
                                        return 1; // Preskocit?
                                    }
                            }
                        } break;
                }
            }

            INodeList L = pSource.CopyMode_CreateSourceList(pRelativeName);
            if (L == null) return 1;

            bool IsFolder;
            using (INode N = new INode())
            {
                using (L)
                {
                    if (L.BeginExpand() == 0)
                    {
                        while (true)
                        {
                            if (L.ExpandNext(null, N) != 1) break;

                            if (pProgressForm != null)
                            {
                                if (pProgressForm.WaitForTerminate.BoolValue) return -1; // Test ukoncenia
                            }

                            string RelFN = pSource.CopyMode_MakeRelative(IFileSystem.AppendToPath(L.CurrentPath, N.Name), out IsFolder); // Ziskam relativnu cestu
                            if (RelFN != "") // Je platna?
                            {
                                if (IsFolder)
                                {
                                    if (Run_MoveItems_Directory(pSource, pDestination, RelFN, pFlags, pProgressForm) == -1) return -1;
                                }
                                else
                                {
                                    while (true)
                                    {
                                        int R = Run_MoveItems_File(pSource, pDestination, RelFN, pFlags, pProgressForm, N);
                                        if (R == -1) return -1; // Prerusit?
                                        if (R != 2) break; // Neopakovat?
                                    }
                                }
                            }
                        }
                        L.CloseExpand();
                    }
                }
            }

            pSource.CopyMode_DeleteFolder(pRelativeName); // Volam vymazanie priecinku
            if (pProgressForm != null) pProgressForm.AddDir();
            return 0; // Vsetko OK
        }
        /// <summary>Presun suboru</summary>
        /// <param name="pSource">zdroj</param>
        /// <param name="pDestination">ciel</param>
        /// <param name="pRelativeName">relativna cesta</param>
        /// <returns>0 - OK, 1 - preskocene, -1 prerusene</returns>
        protected static int Run_MoveItems_File(INodeList pSource, INodeList pDestination, string pRelativeName, IConfirmationFlags pFlags, IFileExplorer_ProgressForm_MoveItems pProgressForm = null, INode pInfoNode = null)
        {
            // Pokusim sa o rychly presun
            if (pSource.CopyMode_FastMoveFile(pRelativeName, pDestination.CopyMode_MakeDestinationFullPath(pRelativeName)) == 0)
            {
                if (pProgressForm != null) pProgressForm.AddFile();
                return 0;
            }

            if (pFlags.OpenSourceFileError != IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL) pFlags.OpenSourceFileError = -1; // Inicializacia
            if (pFlags.CreateDestinationFileError != IConfirmationFlags.COPY_ERROR_SKIP_ALL) pFlags.CreateDestinationFileError = -1;
            if ((pFlags.OverwriteDestinationFile != IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL) && (pFlags.OverwriteDestinationFile != IConfirmationFlags.OVERWRITE_DESTINATION_FILE_YES_ALL)) pFlags.OverwriteDestinationFile = -1;
            if ((pFlags.OverwriteReadOnlyDestinationFile != IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL) && (pFlags.OverwriteReadOnlyDestinationFile != IConfirmationFlags.OVERWRITE_DESTINATION_FILE_YES_ALL)) pFlags.OverwriteReadOnlyDestinationFile = -1;
            if ((pFlags.OverwriteSystemDestinationFile != IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL) && (pFlags.OverwriteSystemDestinationFile != IConfirmationFlags.OVERWRITE_DESTINATION_FILE_YES_ALL)) pFlags.OverwriteSystemDestinationFile = -1;
            if (pFlags.ReadSourceFileError != IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL) pFlags.ReadSourceFileError = -1;
            if (pFlags.WriteDestinationFileError != IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL) pFlags.WriteDestinationFileError = -1;

            while (true)
            {
                if (pProgressForm != null)
                {
                    if (pProgressForm.WaitForTerminate.BoolValue) return -1; // Test ukoncenia
                }

                int R = pSource.CopyMode_OpenReadFile(pRelativeName); // Otvorim zdrojovy subor
                if (R == 0) break;
                switch (R)
                {
                    default:
                        {
                            if (pFlags.OpenSourceFileError == IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL)
                            {
                                if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                return 1; // Preskocit vsetky?
                            }

                            if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_21_4_4, pSource.CopyMode_MakeSourceFullPath(pRelativeName)), lang.FILE_EXPLORER_TEXT_21_4_5, lang.FILE_EXPLORER_TEXT_21_4_6, ref pFlags.OpenSourceFileError)) return -1;
                            switch (pFlags.OpenSourceFileError)
                            {
                                case IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP:
                                case IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL:
                                    {
                                        if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                        return 1; // Preskocit?
                                    }
                            }
                        } break;
                }
            }

            if (pProgressForm != null) pProgressForm.SetCurrentFileSize(pSource.CopyMode_GetSize(), IFileSystem.ExtractName(pSource.CopyMode_MakeSourceFullPath(pRelativeName)));
            while (true)
            {
                if (pProgressForm != null)
                {
                    if (pProgressForm.WaitForTerminate.BoolValue)
                    {
                        pSource.CopyMode_CloseReadFile();
                        return -1; // Test ukoncenia
                    }
                }

                int R = pDestination.CopyMode_CreateWriteFile(pRelativeName, pSource.CopyMode_GetAttributes(), pSource.CopyMode_GetModifyDate(), pFlags.ForceOverwriteDestinationFile, pFlags.ForceOverwriteReadOnlyDestinationFile, pFlags.ForceOverwriteSystemDestinationFile, pFlags.ForceOverwriteSystemDestinationFile); // Vytvorim cielovy subor
                if (R == 0) break; // OK..

                switch (R)
                {
                    case IFileSystem.FS_ERROR_FILE_EXISTS:
                        {
                            if (pFlags.OverwriteDestinationFile == IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL)
                            {
                                if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                pSource.CopyMode_CloseReadFile();
                                return 1;
                            }

                            if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_21_4_10, pSource.CopyMode_MakeSourceFullPath(pRelativeName)), lang.FILE_EXPLORER_TEXT_21_4_11, lang.FILE_EXPLORER_TEXT_21_4_12, ref pFlags.OverwriteDestinationFile)) return -1;
                            switch (pFlags.OverwriteDestinationFile)
                            {
                                case IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP:
                                case IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL:
                                    {
                                        if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                        pSource.CopyMode_CloseReadFile();
                                        return 1;
                                    }
                            }

                        } break;
                    case IFileSystem.FS_ERROR_READ_ONLY_ATTRIBUTE:
                        {
                            if (pFlags.OverwriteReadOnlyDestinationFile == IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL)
                            {
                                if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                pSource.CopyMode_CloseReadFile();
                                return 1;
                            }
                            if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_21_4_13, pSource.CopyMode_MakeSourceFullPath(pRelativeName)), lang.FILE_EXPLORER_TEXT_21_4_14, lang.FILE_EXPLORER_TEXT_21_4_15, ref pFlags.OverwriteReadOnlyDestinationFile)) return -1;
                            switch (pFlags.OverwriteReadOnlyDestinationFile)
                            {
                                case IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP:
                                case IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL:
                                    {
                                        if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                        pSource.CopyMode_CloseReadFile();
                                        return 1;
                                    }
                            }
                        } break;
                    case IFileSystem.FS_ERROR_SYSTEM_ATTRIBUTE:
                    case IFileSystem.FS_ERROR_HIDDEN_ATTRIBUTE:
                        {
                            if (pFlags.OverwriteSystemDestinationFile == IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL)
                            {
                                if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                pSource.CopyMode_CloseReadFile();
                                return 1;
                            }
                            if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_21_4_16, pSource.CopyMode_MakeSourceFullPath(pRelativeName)), lang.FILE_EXPLORER_TEXT_21_4_17, lang.FILE_EXPLORER_TEXT_21_4_18, ref pFlags.OverwriteSystemDestinationFile)) return -1;
                            switch (pFlags.OverwriteSystemDestinationFile)
                            {
                                case IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP:
                                case IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL:
                                    {
                                        if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                        pSource.CopyMode_CloseReadFile();
                                        return 1;
                                    }
                            }
                        } break;
                    default:
                        {
                            if (pFlags.CreateDestinationFileError == IConfirmationFlags.COPY_ERROR_SKIP_ALL)
                            {
                                if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                pSource.CopyMode_CloseReadFile();
                                return 1; // Preskocit vsetky?
                            }
                            if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_21_4_7, pSource.CopyMode_MakeSourceFullPath(pRelativeName)), lang.FILE_EXPLORER_TEXT_21_4_8, lang.FILE_EXPLORER_TEXT_21_4_9, ref pFlags.CreateDestinationFileError)) return -1;
                            switch (pFlags.CreateDestinationFileError)
                            {
                                case IConfirmationFlags.COPY_ERROR_SKIP:
                                case IConfirmationFlags.COPY_ERROR_SKIP_ALL:
                                    {
                                        pSource.CopyMode_CloseReadFile();
                                        if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                        return 1; // Preskocit vsetky?
                                    }
                            }
                        } break;
                }
            }

            while (true)
            {
                if (pProgressForm != null)
                {
                    if (pProgressForm.WaitForTerminate.BoolValue)
                    {
                        if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                        pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                        pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                        if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                        return -1; // Test ukoncenia
                    }
                }


                int C = pSource.CopyMode_ReadFile(MAX_COPY_BUFFER_SIZE, pSource.CopyMode_DataBuffer); // Citam
                if (C == 0) break; // Koniec
                if (C < 0)
                {
                    if (pFlags.ReadSourceFileError == IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL) // Preskocim?
                    {
                        if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                        pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                        pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                        if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                        return 1;
                    }
                    if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_21_4_19, pSource.CopyMode_MakeSourceFullPath(pRelativeName)), lang.FILE_EXPLORER_TEXT_21_4_20, lang.FILE_EXPLORER_TEXT_21_4_21, ref pFlags.ReadSourceFileError)) return -1;
                    switch (pFlags.ReadSourceFileError)
                    {
                        case IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP:
                        case IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL:
                            {
                                if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                                pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                                pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                                if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                return 1;
                            }
                    }
                    continue;
                }

                while (true)
                {
                    if (pProgressForm != null)
                    {
                        if (pProgressForm.WaitForTerminate.BoolValue)
                        {
                            if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                            pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                            pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                            if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                            return -1; // Test ukoncenia
                        }
                    }

                    int R = pDestination.CopyMode_WriteFile(pSource.CopyMode_DataBuffer, 0, C); // Zapisem
                    if (R == 0) break;
                    switch (R)
                    {
                        case IFileSystem.FS_ERROR_NOT_ENOUGH_SPACE: // Plny disk?
                            {
                                R = 0;
                                if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_21_4_25, pSource.CopyMode_MakeSourceFullPath(pRelativeName)), lang.FILE_EXPLORER_TEXT_21_4_26, lang.FILE_EXPLORER_TEXT_21_4_27, ref R))
                                {
                                    if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                                    pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                                    pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                                    return -1; // Test ukoncenia
                                }
                                if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                                pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                                pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                                return 2; // Opakovat operaciu
                            }
                        default:
                            {
                                if (pFlags.WriteDestinationFileError == IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL) // Preskocim?
                                {
                                    if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                                    pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                                    pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                                    if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                    return 1;
                                }
                                if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_21_4_22, pSource.CopyMode_MakeSourceFullPath(pRelativeName)), lang.FILE_EXPLORER_TEXT_21_4_23, lang.FILE_EXPLORER_TEXT_21_4_24, ref pFlags.WriteDestinationFileError)) return -1;
                                switch (pFlags.WriteDestinationFileError)
                                {
                                    case IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP:
                                    case IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL:
                                        {
                                            if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                                            pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                                            pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                                            if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                            return 1;
                                        }
                                }
                            } break;
                    }

                }
                if (pProgressForm != null) pProgressForm.AddTransferredDataSize(C); // Zaradim data
            }

            if (pProgressForm != null) pProgressForm.AddTransferredDataSize(0); // Koniec prenosu

            pSource.CopyMode_CloseReadFile(true); // Uzatvorim subor
            pDestination.CopyMode_CloseWriteFile(false); // Uzatvorim subor
            if (pProgressForm != null) pProgressForm.AddFile(); // Zaradim subor
            return 0; // Vsetko OK
        }

        /// <summary>Spustenie procesu extrahovania obsahu archivu</summary>
        /// <param name="pArchiveFileName">nazov archivu</param>
        /// <param name="pDestinationPath">cielove umiestnenie</param>
        /// <param name="pDetinationFolder">cielovy priecinok</param>
        /// <param name="pProgressForm">progress form</param>
        /// <returns>true / false</returns>
        public static int Run_ExtractItems(string pArchiveFileName, System.Collections.Generic.List<string> pItems, string pDestinationPath, string pDestinationFolder, IFileExplorer_ProgressForm_ExtractArchive pProgressForm = null, int pSourceConnectionProvider = 0, int pDestinationConnectionProvider = 0)
        {
            INodeList SourceList;

            switch (IFileSystem.GetFileType(pArchiveFileName))
            {
                case IFileSystem.FILE_TYPE_RAR:
                    {
                        SourceList = INodeList.CreateNodeList(pArchiveFileName);
                        if (SourceList == null) return 1; // Chybna zdrojova cesta?
                        using (SourceList)
                        {
                            return ((INodeList_RAR)SourceList).Run_ExtractItems(pItems, pDestinationPath, pDestinationFolder, pProgressForm); // Pre rar volam specialnu rutinu na rozbalenie
                        }
                    }
            }

            IConfirmationFlags Flags = new IConfirmationFlags();

            if (!string.IsNullOrEmpty(pDestinationFolder)) // Bude sa rozbalovat do poadresara?
            {
                while (true)
                {
                    INodeList DestList = INodeList.CreateNodeList(pDestinationPath);
                    if (DestList == null) return 1; // Chybna cielova cesta?
                    using (DestList)  
                    {
                        DestList.BeginDestinationCopyMode();
                        while (true)
                        {
                            int R = DestList.CopyMode_MakeFolder(pDestinationFolder, IWin32.FILE_ATTRIBUTE_NORMAL);
                            if ((R == 0) || (R == IFileSystem.FS_ERROR_DIRECTORY_EXISTS)) break; // OK?
                            if (pProgressForm == null) return 1;

                            R = 0; // Opytam sa ci opakovat...
                            if (pProgressForm.ShowEditor_ChooseFromList(lang.FILE_EXPLORER_TEXT_24_4_28, lang.FILE_EXPLORER_TEXT_24_4_29, lang.FILE_EXPLORER_TEXT_24_4_30, ref R)) return 1;
                        }
                        break;
                    }
                }
                pDestinationPath = IFileSystem.AppendToPath(pDestinationPath, pDestinationFolder);
            }

            SourceList = INodeList.CreateNodeList(pArchiveFileName);
            if (SourceList == null) return 1; // Chybna zdrojova cesta?
            using (SourceList)
            {
                INodeList DestList = INodeList.CreateNodeList(pDestinationPath);
                if (DestList == null) return 1; // Chybna cielova cesta?
                using (INode N = new INode())
                {
                    using (DestList)
                    {
                        SourceList.BeginSourceExtractMode(pItems, pProgressForm);
                        DestList.BeginDestinationCopyMode();

                        while (true)
                        {
                            int R = SourceList.ExtractMode_GetNextSourceItem(N);
                            if (R < 0)
                            {
                                return -1;
                            }
                            if (R != 1) break;
                            
                            string DestRelativeName = N.RelativeName; // Cielova relativna cesta
                            if (!SourceList.ExtractMode_CurrentNeedExpand(ref DestRelativeName)) // Je potrebne ho extrahovat?
                            {
                                SourceList.ExtractMode_SkipCurrentItem(); // Preskocim ho
                                if (pProgressForm != null)
                                {
                                    if (N.IsDirectory) pProgressForm.AddDir(true); else pProgressForm.AddFile(true);
                                }
                                continue;
                            }

                            if (N.IsDirectory)
                            {
                                if (RunExtractItems_Directory(SourceList, DestList, N.RelativeName, DestRelativeName, Flags, N, pProgressForm) == -1) return 1;
                            }
                            else
                            {
                                while (true)
                                {
                                    R = Run_ExtractItems_File(SourceList, DestList, N.RelativeName, DestRelativeName, Flags, N, pProgressForm);
                                    if (R == -1) return 1; // Prerusenie?
                                    if (R != 2) break; // Neopakovat?
                                }
                                if (SourceList.ExtractMode_WasLastItemForExtract(N.RelativeName, false)) return 0;
                            }
                        }
                    }
                }
            }

            return 0; // Vsetko OK
        }
        /// <summary>Extrahovanie suboru</summary>
        /// <param name="pSource">zdroj</param>
        /// <param name="pDestination">ciel</param>
        /// <param name="pRelativeName">relativna cesta</param>
        /// <returns>0 - OK, 1 - preskocene, -1 prerusene</returns>
        protected static int Run_ExtractItems_File(INodeList pSource, INodeList pDestination, string pRelativeName, string pDestRelativeName, IConfirmationFlags pFlags, INode pInfoNode, IFileExplorer_ProgressForm_ExtractArchive pProgressForm = null)
        {
            if (pFlags.OpenSourceFileError != IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL) pFlags.OpenSourceFileError = -1; // Inicializacia
            if (pFlags.CreateDestinationFileError != IConfirmationFlags.COPY_ERROR_SKIP_ALL) pFlags.CreateDestinationFileError = -1;
            if ((pFlags.OverwriteDestinationFile != IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL) && (pFlags.OverwriteDestinationFile != IConfirmationFlags.OVERWRITE_DESTINATION_FILE_YES_ALL)) pFlags.OverwriteDestinationFile = -1;
            if ((pFlags.OverwriteReadOnlyDestinationFile != IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL) && (pFlags.OverwriteReadOnlyDestinationFile != IConfirmationFlags.OVERWRITE_DESTINATION_FILE_YES_ALL)) pFlags.OverwriteReadOnlyDestinationFile = -1;
            if ((pFlags.OverwriteSystemDestinationFile != IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL) && (pFlags.OverwriteSystemDestinationFile != IConfirmationFlags.OVERWRITE_DESTINATION_FILE_YES_ALL)) pFlags.OverwriteSystemDestinationFile = -1;
            if (pFlags.ReadSourceFileError != IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL) pFlags.ReadSourceFileError = -1;
            if (pFlags.WriteDestinationFileError != IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL) pFlags.WriteDestinationFileError = -1;

            while (true)
            {
                if (pProgressForm != null)
                {
                    if (pProgressForm.WaitForTerminate.BoolValue) return -1; // Test ukoncenia
                }

                int R = pSource.ExtractMode_OpenCurrentFileForRead(); // Otvorim zdrojovy subor
                if (R == 0) break;
                switch (R)
                {
                    case IFileSystem.FS_ERROR_USER_ABORTED: return -1;
                    default:
                        {
                            if (pFlags.OpenSourceFileError == IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL)
                            {
                                if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                return 1; // Preskocit vsetky?
                            }

                            if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_24_4_4, pRelativeName), lang.FILE_EXPLORER_TEXT_24_4_5, lang.FILE_EXPLORER_TEXT_24_4_6, ref pFlags.OpenSourceFileError)) return -1;
                            switch (pFlags.OpenSourceFileError)
                            {
                                case IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP:
                                case IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL:
                                    {
                                        if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                        return 1; // Preskocit?
                                    }
                            }
                        } break;
                }
            }

            if (pProgressForm != null) pProgressForm.SetCurrentFileSize(pInfoNode.Size, pSource.ExtractMode_CurrentName());
            while (true)
            {
                if (pProgressForm != null)
                {
                    if (pProgressForm.WaitForTerminate.BoolValue)
                    {
                        pSource.CopyMode_CloseReadFile();
                        return -1; // Test ukoncenia
                    }
                }

                int I = pDestRelativeName.LastIndexOf('\\');
                string FolderName = I == -1 ? "" : pDestRelativeName.Substring(0, I);
                if (FolderName != "") pDestination.CopyMode_MakeFolder(FolderName, IWin32.FILE_ATTRIBUTE_NORMAL);

                int R = pDestination.CopyMode_CreateWriteFile(pDestRelativeName, pInfoNode.Attributes, pInfoNode.DLastModify, pFlags.ForceOverwriteDestinationFile, pFlags.ForceOverwriteReadOnlyDestinationFile, pFlags.ForceOverwriteSystemDestinationFile, pFlags.ForceOverwriteSystemDestinationFile, true); // Vytvorim cielovy subor
                if (R == 0) break; // OK..

                switch (R)
                {
                    case IFileSystem.FS_ERROR_FILE_EXISTS:
                        {
                            if (pFlags.OverwriteDestinationFile == IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL)
                            {
                                if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                pSource.CopyMode_CloseReadFile();
                                return 1;
                            }

                            if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_24_4_10, pSource.CopyMode_MakeSourceFullPath(pRelativeName)), lang.FILE_EXPLORER_TEXT_24_4_11, lang.FILE_EXPLORER_TEXT_24_4_12, ref pFlags.OverwriteDestinationFile)) return -1;
                            switch (pFlags.OverwriteDestinationFile)
                            {
                                case IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP:
                                case IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL:
                                    {
                                        if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                        pSource.CopyMode_CloseReadFile();
                                        return 1;
                                    }
                            }

                        } break;
                    case IFileSystem.FS_ERROR_READ_ONLY_ATTRIBUTE:
                        {
                            if (pFlags.OverwriteReadOnlyDestinationFile == IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL)
                            {
                                if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                pSource.CopyMode_CloseReadFile();
                                return 1;
                            }
                            if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_24_4_13, pSource.CopyMode_MakeSourceFullPath(pRelativeName)), lang.FILE_EXPLORER_TEXT_24_4_14, lang.FILE_EXPLORER_TEXT_24_4_15, ref pFlags.OverwriteReadOnlyDestinationFile)) return -1;
                            switch (pFlags.OverwriteReadOnlyDestinationFile)
                            {
                                case IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP:
                                case IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL:
                                    {
                                        if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                        pSource.CopyMode_CloseReadFile();
                                        return 1;
                                    }
                            }
                        } break;
                    case IFileSystem.FS_ERROR_SYSTEM_ATTRIBUTE:
                    case IFileSystem.FS_ERROR_HIDDEN_ATTRIBUTE:
                        {
                            if (pFlags.OverwriteSystemDestinationFile == IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL)
                            {
                                if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                pSource.CopyMode_CloseReadFile();
                                return 1;
                            }
                            if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_24_4_16, pSource.CopyMode_MakeSourceFullPath(pRelativeName)), lang.FILE_EXPLORER_TEXT_24_4_17, lang.FILE_EXPLORER_TEXT_24_4_18, ref pFlags.OverwriteSystemDestinationFile)) return -1;
                            switch (pFlags.OverwriteSystemDestinationFile)
                            {
                                case IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP:
                                case IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL:
                                    {
                                        if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                        pSource.CopyMode_CloseReadFile();
                                        return 1;
                                    }
                            }
                        } break;
                    default:
                        {
                            if (pFlags.CreateDestinationFileError == IConfirmationFlags.COPY_ERROR_SKIP_ALL)
                            {
                                if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                pSource.CopyMode_CloseReadFile();
                                return 1; // Preskocit vsetky?
                            }
                            if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_24_4_7, pSource.CopyMode_MakeSourceFullPath(pRelativeName)), lang.FILE_EXPLORER_TEXT_24_4_8, lang.FILE_EXPLORER_TEXT_24_4_9, ref pFlags.CreateDestinationFileError)) return -1;
                            switch (pFlags.CreateDestinationFileError)
                            {
                                case IConfirmationFlags.COPY_ERROR_SKIP:
                                case IConfirmationFlags.COPY_ERROR_SKIP_ALL:
                                    {
                                        pSource.CopyMode_CloseReadFile();
                                        if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                        return 1; // Preskocit vsetky?
                                    }
                            }
                        } break;
                }
            }

            while (true)
            {
                if (pProgressForm != null)
                {
                    if (pProgressForm.WaitForTerminate.BoolValue)
                    {
                        if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                        pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                        pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                        if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                        return -1; // Test ukoncenia
                    }
                }


                int C = pSource.ExtractMode_ReadFile(MAX_COPY_BUFFER_SIZE, pSource.CopyMode_NativeDataBuffer); // Citam
                if (C == 0) break; // Koniec
                if (C < 0)
                {
                    if (pFlags.ReadSourceFileError == IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL) // Preskocim?
                    {
                        if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                        pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                        pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                        if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                        return 1;
                    }
                    if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_24_4_19, pSource.CopyMode_MakeSourceFullPath(pRelativeName)), lang.FILE_EXPLORER_TEXT_24_4_20, lang.FILE_EXPLORER_TEXT_24_4_21, ref pFlags.ReadSourceFileError))
                    {
                        if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                        pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                        pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                        if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                        return -1; // Prerusenie
                    }
                    switch (pFlags.ReadSourceFileError)
                    {
                        case IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP:
                        case IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL:
                            {
                                if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                                pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                                pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                                if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                return 1;
                            }
                    }
                    continue;
                }

                while (true)
                {
                    if (pProgressForm != null)
                    {
                        if (pProgressForm.WaitForTerminate.BoolValue)
                        {
                            if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                            pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                            pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                            if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                            return -1; // Prerusenie
                        }
                    }

                    int R = pDestination.CopyMode_WriteFile(pSource.CopyMode_NativeDataBuffer, 0, C); // Zapisem
                    if (R == 0) break;
                    switch (R)
                    {
                        case IFileSystem.FS_ERROR_NOT_ENOUGH_SPACE: // Plny disk?
                            {
                                R = 0;
                                if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_24_4_25, pSource.CopyMode_MakeSourceFullPath(pRelativeName)), lang.FILE_EXPLORER_TEXT_24_4_26, lang.FILE_EXPLORER_TEXT_24_4_27, ref R))
                                {
                                    if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                                    pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                                    pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                                    if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                    return -1; // Test ukoncenia
                                }
                                if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                                pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                                pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                                return 2; // Opakovat operaciu
                            }
                        default:
                            {
                                if (pFlags.WriteDestinationFileError == IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL) // Preskocim?
                                {
                                    if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                                    pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                                    pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                                    if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                    return 1;
                                }
                                if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_24_4_22, pSource.CopyMode_MakeSourceFullPath(pRelativeName)), lang.FILE_EXPLORER_TEXT_24_4_23, lang.FILE_EXPLORER_TEXT_24_4_24, ref pFlags.WriteDestinationFileError))
                                {
                                    if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                                    pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                                    pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                                    if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                    return -1; // Test ukoncenia
                                }

                                switch (pFlags.WriteDestinationFileError)
                                {
                                    case IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP:
                                    case IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL:
                                        {
                                            if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                                            pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                                            pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                                            if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                            return 1;
                                        }
                                }
                            } break;
                    }

                }
                if (pProgressForm != null) pProgressForm.AddTransferredDataSize(C); // Zaradim data
            }

            if (pProgressForm != null) pProgressForm.AddTransferredDataSize(0); // Koniec prenosu

            pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
            pDestination.CopyMode_CloseWriteFile(false); // Uzatvorim subor
            if (pProgressForm != null) pProgressForm.AddFile(); // Zaradim subor
            return 0; // Vsetko OK
        }
        /// <summary>Skopirovanie priecinku</summary>
        /// <param name="pSource">zdroj</param>
        /// <param name="pDestination">ciel</param>
        /// <param name="pRelativeName">relativna cesta</param>
        /// <returns>0 - OK, 1 - preskocene, -1 prerusene</returns>
        protected static int RunExtractItems_Directory(INodeList pSource, INodeList pDestination, string pRelativeName, string pDestRelativeName, IConfirmationFlags pFlags, INode pInfoNode, IFileExplorer_ProgressForm_ExtractArchive pProgressForm = null)
        {
            if (pFlags.CreateErrorFolder != IConfirmationFlags.COPY_ERROR_SKIP_ALL) pFlags.CreateErrorFolder = -1; // Inicializujem potvrdenia

            while (true)
            {
                int R = pDestination.CopyMode_MakeFolder(pDestRelativeName, pSource.CopyMode_GetAttributes(pRelativeName));
                if ((R == 0) || (R == IFileSystem.FS_ERROR_DIRECTORY_EXISTS)) break;
                switch (R)
                {
                    default:
                        {
                            if (pFlags.CreateErrorFolder == IConfirmationFlags.COPY_ERROR_SKIP_ALL)
                            {
                                if (pProgressForm != null) pProgressForm.AddDir(true);
                                return 1; // Preskocit vsetky?
                            }

                            if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_24_4_1, pDestination.CopyMode_MakeDestinationFullPath(pRelativeName)), lang.FILE_EXPLORER_TEXT_24_4_2, lang.FILE_EXPLORER_TEXT_24_4_3, ref pFlags.CreateErrorFolder)) return -1;
                            switch (pFlags.CreateErrorFolder)
                            {
                                case IConfirmationFlags.COPY_ERROR_SKIP:
                                case IConfirmationFlags.COPY_ERROR_SKIP_ALL:
                                    {
                                        if (pProgressForm != null) pProgressForm.AddDir(true);
                                        return 1; // Preskocit?
                                    }
                            }
                        } break;
                }
            }
            if (pProgressForm != null) pProgressForm.AddDir(false);
            return 0; // Vsetko OK
        }

        /// <summary>Spustenie procesu zapisu obsahu priecinov a podpriecinkov do suboru</summary>
        /// <param name="pData">data</param>
        /// <param name="pItems">zoznam poloziek</param>
        /// <param name="pOutputFileName">vystupny subor</param>
        /// <param name="pProgressForm">progress formular</param>
        /// <returns>true / false</returns>
        public static bool RunExportListToFile(IFileExplorerForm_ExportListToFile.IExportListToFileStr pData, System.Collections.Generic.List<string> pItems, string pOutputFileName, IFileExplorer_ProgressForm_ExportListOfItems pProgressForm = null)
        {
            INodeList SourceList = INodeList.CreateNodeList(IFileSystem.ExtractPath(pItems[0]));
            if (SourceList == null) return false;

            using (SourceList) // Pouzijem zoznam
            {
                INodeList DestList = INodeList.CreateNodeList(IFileSystem.ExtractPath(pOutputFileName));
                if (DestList == null) return false;
                System.IO.Stream DestStr;

                using (DestList) // Pouzijem zoznam
                {
                    SourceList.BeginSourceCopyMode();
                    DestList.BeginDestinationCopyMode();

                    int R;

                    while (true)
                    {
                        DestStr = DestList.CopyMode_CreateStreamForWrite(IFileSystem.ExtractName(pOutputFileName), out R, true, true, true, true);
                        if (R == 0) break;
                        R = 0;
                        if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_40_9_1, pOutputFileName), lang.FILE_EXPLORER_TEXT_40_9_2, lang.FILE_EXPLORER_TEXT_40_9_3, ref R)) return false;
                    }

                    pData.SetOutputStream(DestStr); // Nastavim output stream

                    bool IsFolder;
                    foreach (string FN in pItems)
                    {
                        string RelFN = SourceList.CopyMode_MakeRelative(FN, out IsFolder);
                        if (IsFolder)
                        {
                            if (!RunExportListToFile_Dir(pData, RelFN, FN, SourceList, DestList, 1, pProgressForm))
                            {
                                pData.CloseOutputStream();
                                DestList.CopyMode_CloseStreamForWrite(DestStr, true); // Uzatvorim stream
                                return false;
                            }
                            if (pProgressForm != null) pProgressForm.AddDir();
                        }
                        else
                        {
                            pData.AddFile(IFileSystem.ExtractName(FN), FN, SourceList.CopyMode_GetSize(RelFN), SourceList.CopyMode_GetCreationDate(RelFN), SourceList.CopyMode_GetModifyDate(RelFN), SourceList.CopyMode_GetLastAccessDate(RelFN), SourceList.CopyMode_GetAttributes(RelFN));
                            if (pProgressForm != null) pProgressForm.AddFile();
                        }
                    }

                    pData.CloseOutputStream();
                    DestList.CopyMode_CloseStreamForWrite(DestStr, false); // Uzatvorim stream
                }
            }

            return true; // Vsetko OK
        }
        /// <summary>Zapis obsahu priecinku do exportu pre proces RunExportListToFile</summary>
        /// <param name="pData">data</param>
        /// <param name="pRelName">relativny nazov</param>
        /// <param name="pFullName">plny nazov</param>
        /// <param name="pSource">zdrojovy zoznam</param>
        /// <param name="pDestination">cielovy zoznam</param>
        /// <param name="pCurrentDepth">aktualna hlbka</param>
        /// <param name="pProgressForm">progress formular</param>
        /// <returns>true / false</returns>
        protected static bool RunExportListToFile_Dir(IFileExplorerForm_ExportListToFile.IExportListToFileStr pData, string pRelName, string pFullName, INodeList pSource, INodeList pDestination, int pCurrentDepth, IFileExplorer_ProgressForm_ExportListOfItems pProgressForm = null)
        {
            if ((pData.ExportDepth != -1) && (pCurrentDepth > pData.ExportDepth)) return true; // Prekrocena hlbka?

            INodeList L = pSource.CopyMode_CreateSourceList(pRelName);
            if (L == null) return true;

            System.Collections.Generic.List<string> Dirs = new System.Collections.Generic.List<string>();
            using (L) // Pouzijem zoznam
            {
                INode N = new INode();
                bool First = true;
                using (N) // Pouzijem node
                {
                    if (L.BeginExpand() != 0) return true;

                    while (true)
                    {
                        if ((pProgressForm != null) && (pProgressForm.WaitForTerminate.BoolValue)) return false;

                        N.Clear();
                        if (L.ExpandNext(null, N) != 1) break; // Nacitam zaznam

                        if (First)
                        {
                            pData.AddDirectory(pRelName, pFullName, false); // Zaradim priecinok
                            if (pProgressForm != null) pProgressForm.AddDir();
                            First = false;
                        }

                        string FullFN = IFileSystem.AppendToPath(L.CurrentPath, N.Name);
                        if (N.IsDirectory)
                        {
                            Dirs.Add(FullFN);
                        }
                        else
                        {
                            pData.AddFile(N.Name, FullFN, N.Size, N.DCreate, N.DLastModify, N.DLastAccess, N.Attributes);
                            if (pProgressForm != null) pProgressForm.AddFile();
                        }
                    }
                    L.CloseExpand();
                    if (First)
                    {
                        pData.AddDirectory(pRelName, pFullName, true); // Zaradim priecinok
                        if (pProgressForm != null) pProgressForm.AddDir();
                    }
                }
            }

            bool IsFolder;
            foreach (string FN in Dirs)
            {
                string RelFN = pSource.CopyMode_MakeRelative(FN, out IsFolder);
                if (!RunExportListToFile_Dir(pData, RelFN, FN, pSource, pDestination, pCurrentDepth + 1, pProgressForm)) return false;
            }

            return true; // Vsetko OK
        }

        /// <summary>Spustenie procesu rozdelenia suboru</summary>
        /// <param name="pSourcePath">zdrojova cesta</param>
        /// <param name="pDestinationPath">cielova cesta</param>
        /// <param name="pItems">zoznam poloziek na kopirovania</param>
        /// <param name="pProgressForm">formular pre zobrazenie progresu</param>
        /// <param name="pStatData">statisticke data</param>
        /// <returns>true / false</returns>
        public static bool Run_SplitFile(ISplitFileDataStruct pData, IFileExplorer_ProgressForm_SplitFile pProgressForm = null)
        {
            INodeList SourceList = INodeList.CreateNodeList(IFileSystem.ExtractPath(pData.FileNameToSplit)); // Vytvorim zdrojovy zoznam
            if (SourceList == null) return false; // Chyba?

            using (ICRC32 CRC32 = new ICRC32())
            {
                if (pData.CreateCRC) CRC32.Init(); // Inicializujem
                using (SourceList)
                {
                    INodeList DestList = INodeList.CreateNodeList(pData.DestinationPath);
                    if (DestList == null) return false; // Chyba?

                    using (DestList)
                    {
                        SourceList.BeginSourceCopyMode();
                        DestList.BeginDestinationCopyMode();

                        int NumOfFiles = (int)(pData.SourceSize / pData.SplitSize); // Ziskam pocet suborov
                        if (pData.SourceSize != ((long)NumOfFiles * pData.SplitSize)) NumOfFiles++;

                        bool F;
                        string pRelativeName = SourceList.CopyMode_MakeRelative(pData.FileNameToSplit, out F); // Ziskam relativny nazov

                        while (true)
                        {
                            int R = SourceList.CopyMode_OpenReadFile(pRelativeName); // Otvorim subor na citanie
                            if (R == 0) break;
                            R = 0;
                            if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_26_3_1, pRelativeName), lang.FILE_EXPLORER_TEXT_26_3_2, lang.FILE_EXPLORER_TEXT_26_3_3, ref R)) return false; // Opytam sa na zopakovanie
                        }

                        long ToDo = pData.SourceSize;
                        for (int i = 0; i < NumOfFiles; i++)
                        {
                            long PartSize = ToDo > pData.SplitSize ? pData.SplitSize : ToDo; // Velkost aktualnej casti
                            string pPartFileName = pRelativeName + "." + ICore.FormatDECNumber(i + 1, NumOfFiles, 3); // Vytvorim vysledny subor
                            if (pProgressForm != null) pProgressForm.StartPart(pPartFileName, PartSize); // Zacnem progress

                            while (true)
                            {
                                int R = DestList.CopyMode_CreateWriteFile(pPartFileName, IWin32.FILE_ATTRIBUTE_NORMAL, DateTime.Now, true, true, true, true);
                                if (R == 0) break;
                                R = 0;
                                if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_26_4_1, pPartFileName), lang.FILE_EXPLORER_TEXT_26_4_2, lang.FILE_EXPLORER_TEXT_26_4_3, ref R)) return false; // Opytam sa na zopakovanie
                            }

                            int C;
                            while (PartSize > 0)
                            {
                                if ((pProgressForm != null) && (pProgressForm.WaitForTerminate.BoolValue)) return false; // Prerusenie?

                                int C1 = PartSize > MAX_COPY_BUFFER_SIZE ? MAX_COPY_BUFFER_SIZE : (int)PartSize;
                                while (true)
                                {
                                    C = SourceList.CopyMode_ReadFile(C1, SourceList.CopyMode_DataBuffer); // Citam data
                                    if (C >= 0) break;
                                    if (C < 0)
                                    {
                                        int R = 0;
                                        if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_26_5_1, pRelativeName), lang.FILE_EXPLORER_TEXT_26_5_2, lang.FILE_EXPLORER_TEXT_26_5_3, ref R)) return false; // Opytam sa na zopakovanie
                                    }
                                }
                                if (C == 0) break; // Koniec streamu?

                                while (true)
                                {
                                    int R = DestList.CopyMode_WriteFile(SourceList.CopyMode_DataBuffer, 0, C);
                                    if (R >= 0) break;
                                    R = 0;
                                    if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_26_6_1, pPartFileName), lang.FILE_EXPLORER_TEXT_26_6_2, lang.FILE_EXPLORER_TEXT_26_6_3, ref R)) return false; // Opytam sa na zopakovanie
                                }

                                if (pData.CreateCRC) CRC32.AddDataBlock(SourceList.CopyMode_DataBuffer, 0, C);

                                PartSize -= (long)C;
                                if (pProgressForm != null) pProgressForm.AddDoneData(C); // Zaradim do progresu
                            }
                            DestList.CopyMode_CloseWriteFile();
                            if (pProgressForm != null) pProgressForm.UpdateProgress(true); // Aktualizujem pri konci casti

                            ToDo -= pData.SplitSize;
                        }

                        SourceList.CopyMode_CloseReadFile();

                        if (pData.CreateCRC)
                        {
                            CRC32.Finish(); // Ukoncim CRC32
                            System.Text.StringBuilder B = new System.Text.StringBuilder();
                            B.AppendFormat("filename={0}", pRelativeName); B.AppendLine();
                            B.AppendFormat("size={0}", pData.SourceSize); B.AppendLine();
                            B.AppendFormat("crc32={0}", CRC32.HEXValue); B.AppendLine();
                            DestList.CopyMode_WriteTextFile(pRelativeName + ".crc", B.ToString()); // Zapisem do crc suboru
                        }

                        SourceList.CloseCopyMode();
                        DestList.CloseCopyMode();
                    }
                }
            }
            return true; // Vsetko OK
        }
        /// <summary>Spustenie procesu spojenia suborov</summary>
        /// <param name="pData">data</param>
        /// <param name="pProgressForm">progress formular</param>
        /// <returns>true / false</returns>
        public static bool Run_JoinFiles(IJoinFilesDataStruct pData, out string pErrMsg, IFileExplorer_ProgressForm_JoinFiles pProgressForm = null)
        {
            pErrMsg = ""; // Inicializujem chybu

            INodeList SourceList = INodeList.CreateNodeList(IFileSystem.ExtractPath(pData.SourceFiles[0])); // Vytvorim zdrojovy zoznam
            if (SourceList == null) return false; // Chyba?

            using (ICRC32 CRC32 = new ICRC32())
            {
                if (pData.CheckCRC) CRC32.Init(); // Inicializujem
                using (SourceList)
                {
                    INodeList DestList = INodeList.CreateNodeList(pData.DestinationFolder);
                    if (DestList == null) return false; // Chyba?

                    using (DestList)
                    {
                        SourceList.BeginSourceCopyMode();
                        DestList.BeginDestinationCopyMode();

                        while (true) // Vytvorim cielovy subor
                        {
                            int R = DestList.CopyMode_CreateWriteFile(pData.DestinationFileName, IWin32.FILE_ATTRIBUTE_NORMAL, DateTime.Now, true, true, true, true);
                            if (R == 0) break;
                            R = 0;
                            if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_26_4_1, pData.DestinationFileName), lang.FILE_EXPLORER_TEXT_26_4_2, lang.FILE_EXPLORER_TEXT_26_4_3, ref R)) return false; // Opytam sa na zopakovanie
                        }

                        foreach (string FullFN in pData.SourceFiles) // Prechadzam vsetky zdrojove subory
                        {
                            bool IsFolder;
                            string FN = SourceList.CopyMode_MakeRelative(FullFN, out IsFolder); // Ziskam relativny nazov

                            while (true)
                            {
                                int R = SourceList.CopyMode_OpenReadFile(FN); // Otvorim subor na citanie
                                if (R == 0) break;
                                R = 0;
                                if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_26_3_1, FN), lang.FILE_EXPLORER_TEXT_26_3_2, lang.FILE_EXPLORER_TEXT_26_3_3, ref R)) return false; // Opytam sa na zopakovanie
                            }

                            if (pProgressForm != null) pProgressForm.StartPart(FN, SourceList.CopyMode_GetSize());

                            int C;
                            while (true)
                            {
                                if ((pProgressForm != null) && (pProgressForm.WaitForTerminate.BoolValue)) return false;
                                while (true)
                                {
                                    C = SourceList.CopyMode_ReadFile(MAX_COPY_BUFFER_SIZE, SourceList.CopyMode_DataBuffer); // Citam data
                                    if (C >= 0) break;
                                    if (C < 0)
                                    {
                                        int R = 0;
                                        if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_26_5_1, FN), lang.FILE_EXPLORER_TEXT_26_5_2, lang.FILE_EXPLORER_TEXT_26_5_3, ref R)) return false; // Opytam sa na zopakovanie
                                    }
                                }
                                if (C == 0) break; // Koniec streamu?

                                while (true)
                                {
                                    int R = DestList.CopyMode_WriteFile(SourceList.CopyMode_DataBuffer, 0, C);
                                    if (R >= 0) break;
                                    R = 0;
                                    if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_26_6_1, pData.DestinationFileName), lang.FILE_EXPLORER_TEXT_26_6_2, lang.FILE_EXPLORER_TEXT_26_6_3, ref R)) return false; // Opytam sa na zopakovanie
                                }

                                if (pData.CheckCRC) CRC32.AddDataBlock(SourceList.CopyMode_DataBuffer, 0, C);
                                if (pProgressForm != null) pProgressForm.AddDoneData(C);
                            }
                        }

                        if (pData.CheckCRC) // Testovat CRC?
                        {
                            string CRCData;
                            if (SourceList.CopyMode_ReadFromTextFile(pData.DestinationFileName + ".crc", 8192, out CRCData) == 0)
                            {
                                string CRC = pData.TryExtractCRC32Value(CRCData); // Hladam hodnotu
                                if (CRC == "") pErrMsg = lang.FILE_EXPLORER_TEXT_26_9;
                                else
                                {
                                    CRC32.Finish();
                                    if (string.Compare(CRC32.HEXValue, CRC, false) == 0) pErrMsg = lang.FILE_EXPLORER_TEXT_26_11;
                                    else pErrMsg = lang.FILE_EXPLORER_TEXT_26_10;
                                }
                            }
                            else
                            {
                                pErrMsg = lang.FILE_EXPLORER_TEXT_26_8;
                            }
                        }
                        SourceList.CloseCopyMode();
                        DestList.CloseCopyMode();
                    }
                }
            }

            return true;
        }

        /// <summary>Spustenie procesu generovania kontrolnych suctov</summary>
        /// <param name="pData">data</param>
        /// <param name="pProgressForm">progress formular</param>
        /// <returns>true / false</returns>
        public static bool Run_GenerateChecksum(IGenerateChecksumDataStruct pData, IFileExplorer_ProgressForm_GenerateChecksum pProgressForm = null)
        {
            byte[] Buffer = null; // Buffer pre citanie

            INodeList DestList = INodeList.CreateNodeList(pData.DestinationPath); // Vytvorim zoznam cieloveho priecinku
            if (DestList == null) return false;

            System.Collections.Generic.List<System.Text.StringBuilder> Builders = null;
            if (!pData.UseOwnFiles)
            {
                Builders = new System.Collections.Generic.List<System.Text.StringBuilder>();
                for (int i = 0; i < pData.Generators.Count; i++) Builders.Add(new System.Text.StringBuilder());
            }

            using (DestList)
            {
                DestList.BeginDestinationCopyMode();
                foreach (string InFileName in pData.SourceFiles)
                {
                    INodeList SourceList = INodeList.CreateNodeList(IFileSystem.ExtractPath(InFileName));
                    if (SourceList == null) continue;

                    string RelFileName;
                    using (SourceList)
                    {
                        pData.InitGenerators();
                        SourceList.BeginSourceCopyMode();

                        bool IsFolder;
                        RelFileName = SourceList.CopyMode_MakeRelative(InFileName, out IsFolder);

                        int R;
                        while (true)
                        {
                            R = SourceList.CopyMode_OpenReadFile(RelFileName); // Otvorim subor na citanie
                            if (R == 0) break;
                            R = 0;
                            if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_28_2_1, RelFileName), lang.FILE_EXPLORER_TEXT_28_2_2, lang.FILE_EXPLORER_TEXT_28_2_3, ref R)) return false; // Opytam sa na zopakovanie
                        }

                        if (pProgressForm != null) pProgressForm.StartPart(RelFileName, SourceList.CopyMode_GetSize());

                        int C;
                        while (true)
                        {
                            if ((pProgressForm != null) && (pProgressForm.WaitForTerminate.BoolValue)) return false;
                            while (true)
                            {
                                C = SourceList.CopyMode_ReadFile(MAX_COPY_BUFFER_SIZE, SourceList.CopyMode_DataBuffer); // Citam data
                                if (C >= 0) break;
                                if (C < 0)
                                {
                                    R = 0;
                                    if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_28_3_1, RelFileName), lang.FILE_EXPLORER_TEXT_28_3_2, lang.FILE_EXPLORER_TEXT_28_3_3, ref R)) return false; // Opytam sa na zopakovanie
                                }
                            }
                            if (C == 0) break; // Koniec streamu?

                            if ((Buffer == null) || (Buffer.Length < C)) Buffer = new byte[C]; // Alokujem buffer
                            ICore.Unmanaged2ManagedData(C, SourceList.CopyMode_DataBuffer, Buffer); // Prevediem na managed

                            pData.AddData(C, Buffer); // Pocitam
                            if (pProgressForm != null) pProgressForm.AddDoneData(C);
                        }
                    }
                    pData.Finish(); // Ukoncim vypocet

                    if (!pData.UseOwnFiles) // Spolocne subory?
                    {
                        for (int i = 0; i < pData.Generators.Count; i++)
                        {
                            Builders[i].AppendLine(pData.Generators[i].GenerateFileContent(RelFileName)); // Ulozim vysledky pre tento vstupny subor
                        }
                    }
                    else
                    {
                        foreach (IChecksumGenerator G in pData.Generators) // Zapisem kazdy generator do vysledku
                        {
                            string FileData = G.GenerateFileContent(RelFileName); // Data suboru
                            string CRCFileName = RelFileName + "." + IGenerateChecksumDataStruct.GetExtension(G.ID); // Nazov suboru
                            DestList.CopyMode_WriteTextFile(CRCFileName, FileData); // Zapis
                        }
                    }
                }

                if (!pData.UseOwnFiles) // Ulozim do spolocnych suborov?
                {
                    for (int i = 0; i < pData.Generators.Count; i++)
                    {
                        string CRCFileName = pData.CommonFileName + "." + IGenerateChecksumDataStruct.GetExtension(pData.Generators[i].ID); // Nazov suboru
                        DestList.CopyMode_WriteTextFile(CRCFileName, Builders[i].ToString()); // Zapis
                    }
                }
            }

            return true; // OK
        }
        /// <summary>Spustenie procesu overenia kontrolnych suctov</summary>
        /// <param name="pData">data overovania</param>
        /// <param name="pProgressForm">progress formular</param>
        /// <returns>true / false</returns>
        public static bool Run_VerifyChecksum(IVerifyChecksumDataStruct pData, IFileExplorer_ProgressForm_VerifyChecksum pProgressForm = null)
        {
            byte[] Buffer = null; // Buffer pre citanie

            for (int i = 0; i < pData.Items.Count; i++)
            {
                INodeList SourceList = INodeList.CreateNodeList(IFileSystem.ExtractPath(pData.Items[i].SourceFileName));
                if (SourceList == null) continue;

                using (SourceList)
                {
                    SourceList.BeginSourceCopyMode();

                    bool IsFolder;
                    string FileName = SourceList.CopyMode_MakeRelative(pData.Items[i].SourceFileName, out IsFolder);

                    int R;
                    while (true)
                    {
                        R = SourceList.CopyMode_OpenReadFile(FileName); // Otvorim subor na citanie
                        if (R == 0) break;
                        R = 0;
                        if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_29_2_1, FileName), lang.FILE_EXPLORER_TEXT_29_2_2, lang.FILE_EXPLORER_TEXT_29_2_3, ref R)) return false; // Opytam sa na zopakovanie
                    }

                    if (pProgressForm != null) pProgressForm.StartPart(FileName, SourceList.CopyMode_GetSize());

                    using (IChecksumGenerator G = IChecksumGenerator.CreateGenerator(pData.Items[i].ChecksumType))
                    {
                        G.Init(); // Inicializujem kalkulator

                        int C;
                        while (true)
                        {
                            if ((pProgressForm != null) && (pProgressForm.WaitForTerminate.BoolValue)) return false;
                            while (true)
                            {
                                C = SourceList.CopyMode_ReadFile(MAX_COPY_BUFFER_SIZE, SourceList.CopyMode_DataBuffer); // Citam data
                                if (C >= 0) break;
                                if (C < 0)
                                {
                                    R = 0;
                                    if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_29_3_1, FileName), lang.FILE_EXPLORER_TEXT_29_3_2, lang.FILE_EXPLORER_TEXT_29_3_3, ref R)) return false; // Opytam sa na zopakovanie
                                }
                            }
                            if (C == 0) break; // Koniec streamu?

                            if ((Buffer == null) || (Buffer.Length < C)) Buffer = new byte[C]; // Alokujem buffer
                            ICore.Unmanaged2ManagedData(C, SourceList.CopyMode_DataBuffer, Buffer); // Prevediem na managed

                            G.AddData(C, Buffer); // Pocitam
                            if (pProgressForm != null) pProgressForm.AddDoneData(C);
                        }
                        G.Finish(); // Uzatvorim vypocet

                        pData.Items[i].ExpectedChecksum = pData.Items[i].UserChecksum; // Urcim cielovy kontrolny sucet
                        if (pData.Items[i].ChecksumFileName != "")
                        {
                            string S;
                            if (!IVerifyChecksumDataStruct.ExtractChecksumFromFile(pData.Items[i].ChecksumFileName, FileName, out S, out pData.Items[i].ExpectedChecksum)) pData.Items[i].ExpectedChecksum = "";
                        }
                        pData.Items[i].ExpectedChecksum = pData.Items[i].ExpectedChecksum.ToLower(); // Odlozene ocakavany kontrolny sucet
                        pData.Items[i].ResultChecksum = G.HEX_VALUE.ToLower(); // Ulozeny vypocitany sucet
                    }
                }

            }
            return true; // 
        }

        /// <summary>Spustenie procesu vytvorenia archivu</summary>
        /// <param name="pData">data</param>
        /// <param name="pItems">zoznam poloziek na archivaciu</param>
        /// <param name="pProgressForm">progress formular</param>
        /// <returns>true / false</returns>
        public static bool Run_CreateArchive(ICompressionDataStr pData, System.Collections.Generic.List<string> pItems, IFileExplorer_ProgressForm_CompressItems pProgressForm = null)
        {
            switch (pData.CompressionType)
            {
                case ICompressionDataStr.COMPRESSION_TYPE_ZIP: return INodeList_ZIP.Run_CreateArchive_ZIP(pData, pItems, pProgressForm); // ZIP?
                case ICompressionDataStr.COMPRESSION_TYPE_TGZ:
                case ICompressionDataStr.COMPRESSION_TYPE_TAR: return INodeList_TAR.Run_CreateArchive_TAR(pData, pItems, pProgressForm); // TAR?
                case ICompressionDataStr.COMPRESSION_TYPE_GZIP: return INodeList_GZIP.Run_CreateArchive_GZIP(pData, pItems, pProgressForm); // GZIP?
                default: return false; // Neznama kompresia
            }
        }

        /// <summary>Spustenie procesu sifrovania</summary>
        /// <param name="pData">data</param>
        /// <param name="pItems">zoznam suborov</param>
        /// <param name="pProgressForm">progress formular</param>
        /// <returns>true / false</returns>
        public static bool Run_EncryptFiles(IEncryptionSettingsStr pData, System.Collections.Generic.List<string> pItems, IFileExplorer_ProgressForm_EncryptFiles pProgressForm = null, int pSourceConnectionProvider = 0, int pDestinationConnectionProvider = 0)
        {
            IConfirmationFlags Flags = new IConfirmationFlags(); // Priznaky

            INodeList SourceList = INodeList.CreateNodeList(IFileSystem.ExtractPath(pItems[0]), pSourceConnectionProvider);
            if (SourceList == null) return false; // Prerusim

            using (SourceList) // Pouzijem zoznam
            {
                INodeList DestList = INodeList.CreateNodeList(pData.OutputPath, pDestinationConnectionProvider);
                if (DestList == null) return false; // Chyba?
                using (DestList) // Pouzijem zoznam
                {
                    SourceList.BeginSourceCopyMode();
                    if (SourceList.FState != 2) return false; // Nepodarila sa inicializacia?

                    DestList.BeginDestinationCopyMode();
                    if (DestList.FState != 3) return false; // Nepodarila sa inicializacia?

                    bool IsFolder;
                    foreach (string FN in pItems)
                    {
                        string RelFN = SourceList.CopyMode_MakeRelative(FN, out IsFolder);
                        if (RelFN == "") continue; // Preskocim neplatny subor

                        if (Run_EncryptFiles_File(pData, Flags, SourceList, DestList, RelFN, pProgressForm) == -1) return false;
                    }
                }
            }

            return true; // Vsetko OK
        }
        /// <summary>Spustenie procesu sifrovania jedneho suboru</summary>
        /// <param name="pData">data</param>
        /// <param name="pFlags">priznaky</param>
        /// <param name="pSource">zdrojovy zoznam</param>
        /// <param name="pDestination">cielovy zoznam</param>
        /// <param name="pRelFileName">relativne meno suboru</param>
        /// <param name="pProgressForm">progress formular</param>
        /// <returns>0 - OK, 1 - preskocene, -1 prerusene</returns>
        protected static int Run_EncryptFiles_File(IEncryptionSettingsStr pData, IConfirmationFlags pFlags, INodeList pSource, INodeList pDestination, string pRelFileName, IFileExplorer_ProgressForm_EncryptFiles pProgressForm = null)
        {
            if (pFlags.OpenSourceFileError != IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL) pFlags.OpenSourceFileError = -1; // Inicializacia
            if (pFlags.CreateDestinationFileError != IConfirmationFlags.COPY_ERROR_SKIP_ALL) pFlags.CreateDestinationFileError = -1;
            if ((pFlags.OverwriteDestinationFile != IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL) && (pFlags.OverwriteDestinationFile != IConfirmationFlags.OVERWRITE_DESTINATION_FILE_YES_ALL)) pFlags.OverwriteDestinationFile = -1;
            if ((pFlags.OverwriteReadOnlyDestinationFile != IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL) && (pFlags.OverwriteReadOnlyDestinationFile != IConfirmationFlags.OVERWRITE_DESTINATION_FILE_YES_ALL)) pFlags.OverwriteReadOnlyDestinationFile = -1;
            if ((pFlags.OverwriteSystemDestinationFile != IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL) && (pFlags.OverwriteSystemDestinationFile != IConfirmationFlags.OVERWRITE_DESTINATION_FILE_YES_ALL)) pFlags.OverwriteSystemDestinationFile = -1;
            if (pFlags.ReadSourceFileError != IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL) pFlags.ReadSourceFileError = -1;
            if (pFlags.WriteDestinationFileError != IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL) pFlags.WriteDestinationFileError = -1;

            int R;
            while (true)
            {
                if (pProgressForm != null)
                {
                    if (pProgressForm.WaitForTerminate.BoolValue) return -1; // Test ukoncenia
                }

                R = pSource.CopyMode_OpenReadFile(pRelFileName, null); // Otvorim zdrojovy subor
                if (R == 0) break;
                switch (R)
                {
                    default:
                        {
                            if (pFlags.OpenSourceFileError == IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL)
                            {
                                if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                return 1; // Preskocit vsetky?
                            }

                            if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_41_4_1, pSource.CopyMode_MakeSourceFullPath(pRelFileName)), lang.FILE_EXPLORER_TEXT_41_4_2, lang.FILE_EXPLORER_TEXT_41_4_3, ref pFlags.OpenSourceFileError)) return -1;
                            switch (pFlags.OpenSourceFileError)
                            {
                                case IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP:
                                case IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL:
                                    {
                                        if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                        return 1; // Preskocit?
                                    }
                            }
                        } break;
                }
            }

            string OutFN = pRelFileName + ".tlm_enc";
            uint CRC = 0;

            System.IO.Stream DestStream;
            while(true) {
                DestStream = pDestination.CopyMode_CreateStreamForWrite(OutFN, out R, pFlags.ForceOverwriteDestinationFile, pFlags.ForceOverwriteReadOnlyDestinationFile, pFlags.ForceOverwriteSystemDestinationFile, pFlags.ForceOverwriteSystemDestinationFile); // Vytvorim cielovy subor
                if (R == 0) break; // OK..

                switch (R)
                {
                    case IFileSystem.FS_ERROR_FILE_EXISTS:
                        {
                            if (pFlags.OverwriteDestinationFile == IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL) 
                            {
                                if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                pSource.CopyMode_CloseReadFile();
                                return 1;
                            }

                            if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_41_4_4, pDestination.CopyMode_MakeSourceFullPath(OutFN)), lang.FILE_EXPLORER_TEXT_41_4_5, lang.FILE_EXPLORER_TEXT_41_4_6, ref pFlags.OverwriteDestinationFile)) return -1;
                            switch (pFlags.OverwriteDestinationFile)
                            {
                                case IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP:
                                case IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL:
                                    {
                                        if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                        pSource.CopyMode_CloseReadFile();
                                        return 1;
                                    }
                            }

                        } break;
                    case IFileSystem.FS_ERROR_READ_ONLY_ATTRIBUTE:
                        {
                            if (pFlags.OverwriteReadOnlyDestinationFile == IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL)
                            {
                                if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                pSource.CopyMode_CloseReadFile();
                                return 1;
                            }
                            if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_41_4_7, pDestination.CopyMode_MakeSourceFullPath(OutFN)), lang.FILE_EXPLORER_TEXT_41_4_8, lang.FILE_EXPLORER_TEXT_41_4_9, ref pFlags.OverwriteReadOnlyDestinationFile)) return -1;
                            switch (pFlags.OverwriteReadOnlyDestinationFile)
                            {
                                case IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP:
                                case IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL:
                                    {
                                        if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                        pSource.CopyMode_CloseReadFile();
                                        return 1;
                                    }
                            }
                        } break;
                    case IFileSystem.FS_ERROR_SYSTEM_ATTRIBUTE:
                    case IFileSystem.FS_ERROR_HIDDEN_ATTRIBUTE:
                        {
                            if (pFlags.OverwriteSystemDestinationFile == IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL)
                            {
                                if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                pSource.CopyMode_CloseReadFile();
                                return 1;
                            }
                            if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_41_4_10, pDestination.CopyMode_MakeSourceFullPath(OutFN)), lang.FILE_EXPLORER_TEXT_41_4_11, lang.FILE_EXPLORER_TEXT_41_4_12, ref pFlags.OverwriteSystemDestinationFile)) return -1;
                            switch (pFlags.OverwriteSystemDestinationFile)
                            {
                                case IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP:
                                case IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL:
                                    {
                                        if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                        pSource.CopyMode_CloseReadFile();
                                        return 1;
                                    }
                            }
                        } break;
                    default:
                        {
                            if (pFlags.CreateDestinationFileError == IConfirmationFlags.COPY_ERROR_SKIP_ALL)
                            {
                                if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                pSource.CopyMode_CloseReadFile();
                                return 1; // Preskocit vsetky?
                            }
                            if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_41_4_13, pDestination.CopyMode_MakeSourceFullPath(OutFN)), lang.FILE_EXPLORER_TEXT_41_4_14, lang.FILE_EXPLORER_TEXT_41_4_15, ref pFlags.CreateDestinationFileError)) return -1;
                            switch (pFlags.CreateDestinationFileError)
                            {
                                case IConfirmationFlags.COPY_ERROR_SKIP:
                                case IConfirmationFlags.COPY_ERROR_SKIP_ALL:
                                    {
                                        pSource.CopyMode_CloseReadFile();
                                        if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                        return 1; // Preskocit vsetky?
                                    }
                            }
                        } break;
                }
            }

            byte[] Buffer = new byte[MAX_COPY_BUFFER_SIZE];
            IEncryptor Encryptor = IEncryptor.CreateEncryptor(pData.EncryptionType); // Vytvorim encryptor
            Encryptor.OriginalName = IFileSystem.ExtractName(pSource.CopyMode_MakeSourceFullPath(pRelFileName));
            Encryptor.OriginalSize = pSource.CopyMode_GetSize();
            if (pData.PasswordMode) Encryptor.Init(pData.Password, DestStream);
            else Encryptor.Init(pData.RawPassword, DestStream);

            if (pProgressForm != null) pProgressForm.SetCurrentFileSize(pSource.CopyMode_GetSize(), pRelFileName);

            using (Encryptor)
            {
                while (true)
                {
                    if (pProgressForm != null)
                    {
                        if (pProgressForm.WaitForTerminate.BoolValue)
                        {
                            pSource.CopyMode_AbortOperation(); pDestination.CopyMode_AbortOperation(); // Prerusim operacie
                            if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                            pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                            pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                            if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                            return -1; // Test ukoncenia
                        }
                    }

                    int C = pSource.CopyMode_ReadFile(MAX_COPY_BUFFER_SIZE, Buffer); // Citam
                    if (C == 0) break; // Koniec
                    if (C < 0)
                    {
                        if (pFlags.ReadSourceFileError == IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL) // Preskocim?
                        {
                            pSource.CopyMode_AbortOperation(); pDestination.CopyMode_AbortOperation(); // Prerusim operacie
                            if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                            pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                            pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                            if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                            return 1;
                        }
                        if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_41_4_16, pSource.CopyMode_MakeSourceFullPath(pRelFileName)), lang.FILE_EXPLORER_TEXT_41_4_17, lang.FILE_EXPLORER_TEXT_41_4_18, ref pFlags.ReadSourceFileError))
                        {
                            pSource.CopyMode_AbortOperation(); pDestination.CopyMode_AbortOperation(); // Prerusim operacie
                            if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                            pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                            pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                            if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                            return -1; // Prerusenie
                        }
                        switch (pFlags.ReadSourceFileError)
                        {
                            case IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP:
                            case IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL:
                                {
                                    pSource.CopyMode_AbortOperation(); pDestination.CopyMode_AbortOperation(); // Prerusim operacie
                                    if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                                    pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                                    pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                                    if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                    return 1;
                                }
                        }
                        continue;
                    }

                    for (int i = 0; i < C; i++) CRC += Buffer[i]; // Aktualizujem CRC

                    while (true)
                    {
                        if (pProgressForm != null)
                        {
                            if (pProgressForm.WaitForTerminate.BoolValue)
                            {
                                pSource.CopyMode_AbortOperation(); pDestination.CopyMode_AbortOperation(); // Prerusim operacie
                                if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                                pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                                pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                                if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                return -1; // Prerusenie
                            }
                        }

                        R = Encryptor.WriteData(Buffer, C);
                        if (R == 0) break;

                        pSource.CopyMode_AbortOperation(); pDestination.CopyMode_AbortOperation(); // Prerusim operacie
                        if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                        pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                        pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                        if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor

                        if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_41_4_19, pDestination.CopyMode_MakeSourceFullPath(OutFN)), lang.FILE_EXPLORER_TEXT_41_4_20, lang.FILE_EXPLORER_TEXT_41_4_21, ref pFlags.WriteDestinationFileError))
                        {
                            return -1; // Test ukoncenia
                        }
                        return 1;
                    }
                    if (pProgressForm != null) pProgressForm.AddTransferredDataSize(C); // Zaradim data
                }

                try
                {
                    Encryptor.WriteData(BitConverter.GetBytes(CRC), 4); // Zapisem CRC
                }
                catch
                {
                    pSource.CopyMode_AbortOperation(); pDestination.CopyMode_AbortOperation(); // Prerusim operacie
                    if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                    pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
                    pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                    if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor

                    if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_41_4_19, pDestination.CopyMode_MakeSourceFullPath(OutFN)), lang.FILE_EXPLORER_TEXT_41_4_20, lang.FILE_EXPLORER_TEXT_41_4_21, ref pFlags.WriteDestinationFileError))
                    {
                        return -1; // Test ukoncenia
                    }
                    return 1;
                }

            }

            pDestination.CopyMode_CloseStreamForWrite(DestStream, false);
            pSource.CopyMode_CloseReadFile(); // Uzatvorim subor
            if (pProgressForm != null) pProgressForm.AddFile(false);
            return 0; // Vsetko OK
        }

        /// <summary>Spustenie procesu sifrovania</summary>
        /// <param name="pData">data</param>
        /// <param name="pItems">zoznam suborov</param>
        /// <param name="pProgressForm">progress formular</param>
        /// <returns>true / false</returns>
        public static bool Run_DecryptFiles(IDecryptionSettingsStr pData, string pOutputPath, System.Collections.Generic.List<string> pItems, IFileExplorer_ProgressForm_DecryptFiles pProgressForm = null, int pSourceConnectionProvider = 0, int pDestinationConnectionProvider = 0)
        {
            IConfirmationFlags Flags = new IConfirmationFlags(); // Priznaky

            INodeList SourceList = INodeList.CreateNodeList(IFileSystem.ExtractPath(pItems[0]), pSourceConnectionProvider);
            if (SourceList == null) return false; // Prerusim

            using (SourceList) // Pouzijem zoznam
            {
                INodeList DestList = INodeList.CreateNodeList(pOutputPath, pDestinationConnectionProvider);
                if (DestList == null) return false; // Chyba?
                using (DestList) // Pouzijem zoznam
                {
                    SourceList.BeginSourceCopyMode();
                    if (SourceList.FState != 2) return false; // Nepodarila sa inicializacia?

                    DestList.BeginDestinationCopyMode();
                    if (DestList.FState != 3) return false; // Nepodarila sa inicializacia?

                    bool IsFolder;
                    foreach (string FN in pItems)
                    {
                        string RelFN = SourceList.CopyMode_MakeRelative(FN, out IsFolder);
                        if (RelFN == "") continue; // Preskocim neplatny subor

                        if (Run_DecryptFiles_File(pData, Flags, SourceList, DestList, RelFN, pProgressForm) == -1) return false;
                    }
                }
            }

            return true; // Vsetko OK
        }
        /// <summary>Spustenie procesu sifrovania jedneho suboru</summary>
        /// <param name="pData">data</param>
        /// <param name="pFlags">priznaky</param>
        /// <param name="pSource">zdrojovy zoznam</param>
        /// <param name="pDestination">cielovy zoznam</param>
        /// <param name="pRelFileName">relativne meno suboru</param>
        /// <param name="pProgressForm">progress formular</param>
        /// <returns>0 - OK, 1 - preskocene, -1 prerusene</returns>
        protected static int Run_DecryptFiles_File(IDecryptionSettingsStr pData, IConfirmationFlags pFlags, INodeList pSource, INodeList pDestination, string pRelFileName, IFileExplorer_ProgressForm_DecryptFiles pProgressForm = null)
        {
            if (pFlags.OpenSourceFileError != IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL) pFlags.OpenSourceFileError = -1; // Inicializacia
            if (pFlags.CreateDestinationFileError != IConfirmationFlags.COPY_ERROR_SKIP_ALL) pFlags.CreateDestinationFileError = -1;
            if ((pFlags.OverwriteDestinationFile != IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL) && (pFlags.OverwriteDestinationFile != IConfirmationFlags.OVERWRITE_DESTINATION_FILE_YES_ALL)) pFlags.OverwriteDestinationFile = -1;
            if ((pFlags.OverwriteReadOnlyDestinationFile != IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL) && (pFlags.OverwriteReadOnlyDestinationFile != IConfirmationFlags.OVERWRITE_DESTINATION_FILE_YES_ALL)) pFlags.OverwriteReadOnlyDestinationFile = -1;
            if ((pFlags.OverwriteSystemDestinationFile != IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL) && (pFlags.OverwriteSystemDestinationFile != IConfirmationFlags.OVERWRITE_DESTINATION_FILE_YES_ALL)) pFlags.OverwriteSystemDestinationFile = -1;
            if (pFlags.ReadSourceFileError != IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL) pFlags.ReadSourceFileError = -1;
            if (pFlags.WriteDestinationFileError != IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL) pFlags.WriteDestinationFileError = -1;
            if (pFlags.CheckIntegritySourceFileError != IConfirmationFlags.CHECK_INTEGRITY_SOURCE_ERROR_SKIP_ALL) pFlags.CheckIntegritySourceFileError = -1;

            int R;
            System.IO.Stream SourceStream;

            while (true)
            {
                if (pProgressForm != null)
                {
                    if (pProgressForm.WaitForTerminate.BoolValue) return -1; // Test ukoncenia
                }

                SourceStream = pSource.CopyMode_OpenStreamForRead(pRelFileName, out R); // Otvorim zdrojovy subor
                if (R == 0) break;
                switch (R)
                {
                    default:
                        {
                            if (pFlags.OpenSourceFileError == IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL)
                            {
                                if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                return 1; // Preskocit vsetky?
                            }

                            if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_42_3_1, pSource.CopyMode_MakeSourceFullPath(pRelFileName)), lang.FILE_EXPLORER_TEXT_42_3_2, lang.FILE_EXPLORER_TEXT_42_3_3, ref pFlags.OpenSourceFileError)) return -1;
                            switch (pFlags.OpenSourceFileError)
                            {
                                case IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP:
                                case IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL:
                                    {
                                        if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                        return 1; // Preskocit?
                                    }
                            }
                        } break;
                }
            }

            IDecryptor Decryptor = IDecryptor.OpenDecryptor(SourceStream, out R);
            if (R != 0)
            {
                pSource.CopyMode_CloseStreamForRead(SourceStream, false);
                if (pFlags.OverwriteDestinationFile != IConfirmationFlags.OVERWRITE_DESTINATION_FILE_YES_ALL)
                {
                    if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_42_3_4, pSource.CopyMode_MakeSourceFullPath(pRelFileName)), lang.FILE_EXPLORER_TEXT_42_3_5, lang.FILE_EXPLORER_TEXT_42_3_6, ref pFlags.OverwriteDestinationFile)) return -1;
                }
                if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                return 1; // Preskocim
            }

            using (Decryptor)
            {
                string Pwd = "";
                switch (pData.PasswordMode)
                {
                    case 0:
                        {
                            Pwd = pData.Password;
                            Decryptor.Init(Pwd, SourceStream);
                        } break;
                    case 1:
                        {
                            Decryptor.Init(pData.RawPassword, SourceStream);
                        } break;
                    case 2:
                        {
                            if (pProgressForm != null)
                            {
                                if (!pProgressForm.ShowEditor_EditString(string.Format(lang.FILE_EXPLORER_TEXT_42_5_1, pSource.CopyMode_MakeSourceFullPath(pRelFileName)), ref Pwd, false, -1, null, null, true))
                                {
                                    pSource.CopyMode_AbortOperation(); pDestination.CopyMode_AbortOperation(); // Prerusim operacie
                                    if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                                    Decryptor.Close();
                                    pSource.CopyMode_CloseStreamForRead(SourceStream, false); // Uzatvorim subor
                                    pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                                    if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                    return -1; // Test ukoncenia
                                }
                            }
                            Decryptor.Init(Pwd, SourceStream);
                        } break;
                }

                string OutFN = Decryptor.OriginalName;
                if (OutFN == "") OutFN = IFileSystem.ExtractNameOnly(IFileSystem.ExtractName(pSource.CopyMode_MakeSourceFullPath(pRelFileName)));

                while (true)
                {
                    R = pDestination.CopyMode_CreateWriteFile(OutFN, IWin32.FILE_ATTRIBUTE_NORMAL, DateTime.Now, pFlags.ForceOverwriteDestinationFile, pFlags.ForceOverwriteReadOnlyDestinationFile, pFlags.ForceOverwriteSystemDestinationFile, pFlags.ForceOverwriteSystemDestinationFile, true); // Vytvorim cielovy subor
                    if (R == 0) break; // OK..

                    switch (R)
                    {
                        case IFileSystem.FS_ERROR_FILE_EXISTS:
                            {
                                if (pFlags.OverwriteDestinationFile == IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL)
                                {
                                    if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                    pSource.CopyMode_CloseReadFile();
                                    return 1;
                                }

                                if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_42_4_4, pDestination.CopyMode_MakeSourceFullPath(OutFN)), lang.FILE_EXPLORER_TEXT_42_4_5, lang.FILE_EXPLORER_TEXT_42_4_6, ref pFlags.OverwriteDestinationFile)) return -1;
                                switch (pFlags.OverwriteDestinationFile)
                                {
                                    case IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP:
                                    case IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL:
                                        {
                                            if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                            pSource.CopyMode_CloseReadFile();
                                            return 1;
                                        }
                                }

                            } break;
                        case IFileSystem.FS_ERROR_READ_ONLY_ATTRIBUTE:
                            {
                                if (pFlags.OverwriteReadOnlyDestinationFile == IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL)
                                {
                                    if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                    pSource.CopyMode_CloseReadFile();
                                    return 1;
                                }
                                if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_42_4_7, pDestination.CopyMode_MakeSourceFullPath(OutFN)), lang.FILE_EXPLORER_TEXT_42_4_8, lang.FILE_EXPLORER_TEXT_42_4_9, ref pFlags.OverwriteReadOnlyDestinationFile)) return -1;
                                switch (pFlags.OverwriteReadOnlyDestinationFile)
                                {
                                    case IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP:
                                    case IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL:
                                        {
                                            if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                            pSource.CopyMode_CloseReadFile();
                                            return 1;
                                        }
                                }
                            } break;
                        case IFileSystem.FS_ERROR_SYSTEM_ATTRIBUTE:
                        case IFileSystem.FS_ERROR_HIDDEN_ATTRIBUTE:
                            {
                                if (pFlags.OverwriteSystemDestinationFile == IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL)
                                {
                                    if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                    pSource.CopyMode_CloseReadFile();
                                    return 1;
                                }
                                if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_42_4_10, pDestination.CopyMode_MakeSourceFullPath(OutFN)), lang.FILE_EXPLORER_TEXT_42_4_11, lang.FILE_EXPLORER_TEXT_42_4_12, ref pFlags.OverwriteSystemDestinationFile)) return -1;
                                switch (pFlags.OverwriteSystemDestinationFile)
                                {
                                    case IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP:
                                    case IConfirmationFlags.OVERWRITE_DESTINATION_FILE_SKIP_ALL:
                                        {
                                            if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                            pSource.CopyMode_CloseReadFile();
                                            return 1;
                                        }
                                }
                            } break;
                        default:
                            {
                                if (pFlags.CreateDestinationFileError == IConfirmationFlags.COPY_ERROR_SKIP_ALL)
                                {
                                    if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                    pSource.CopyMode_CloseReadFile();
                                    return 1; // Preskocit vsetky?
                                }
                                if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_42_4_13, pDestination.CopyMode_MakeSourceFullPath(OutFN)), lang.FILE_EXPLORER_TEXT_42_4_14, lang.FILE_EXPLORER_TEXT_42_4_15, ref pFlags.CreateDestinationFileError)) return -1;
                                switch (pFlags.CreateDestinationFileError)
                                {
                                    case IConfirmationFlags.COPY_ERROR_SKIP:
                                    case IConfirmationFlags.COPY_ERROR_SKIP_ALL:
                                        {
                                            pSource.CopyMode_CloseReadFile();
                                            if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                            return 1; // Preskocit vsetky?
                                        }
                                }
                            } break;
                    }
                }

                if (pProgressForm != null) pProgressForm.SetCurrentFileSize(Decryptor.OriginalSize, pRelFileName);
                long ToRead = Decryptor.OriginalSize;
                uint CRC = 0;

                byte[] Buffer = new byte[MAX_COPY_BUFFER_SIZE];
                while (ToRead > 0)
                {
                    if (pProgressForm != null)
                    {
                        if (pProgressForm.WaitForTerminate.BoolValue)
                        {
                            pSource.CopyMode_AbortOperation(); pDestination.CopyMode_AbortOperation(); // Prerusim operacie
                            if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                            Decryptor.Close();
                            pSource.CopyMode_CloseStreamForRead(SourceStream, false); // Uzatvorim subor
                            pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                            if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                            return -1; // Test ukoncenia
                        }
                    }

                    int C;
                    while (true)
                    {
                        int C1 = ToRead > MAX_COPY_BUFFER_SIZE ? MAX_COPY_BUFFER_SIZE : (int)ToRead;
                        C = Decryptor.ReadData(Buffer, C1); // Citam
                        if (C >= 0) break;
                        if (C == -2) // Chyba desifrovania?
                        {
                            pSource.CopyMode_AbortOperation(); pDestination.CopyMode_AbortOperation(); // Prerusim operacie
                            if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                            Decryptor.Close();
                            pSource.CopyMode_CloseStreamForRead(SourceStream, false); // Uzatvorim subor
                            pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                            if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor

                            if (pFlags.CheckIntegritySourceFileError != IConfirmationFlags.CHECK_INTEGRITY_SOURCE_ERROR_SKIP_ALL)
                            {
                                if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_42_4_22, pDestination.CopyMode_MakeSourceFullPath(OutFN)), lang.FILE_EXPLORER_TEXT_42_4_23, lang.FILE_EXPLORER_TEXT_42_4_24, ref pFlags.CheckIntegritySourceFileError))
                                {
                                    return -1; // Test ukoncenia
                                }
                                return 1;
                            }
                        }

                        // Chyba citania
                        if (pFlags.ReadSourceFileError == IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL) // Preskocim?
                        {
                            pSource.CopyMode_AbortOperation(); pDestination.CopyMode_AbortOperation(); // Prerusim operacie
                            if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                            Decryptor.Close();
                            pSource.CopyMode_CloseStreamForRead(SourceStream, false); // Uzatvorim subor
                            pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                            if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                            return 1;
                        }
                        if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_42_4_16, pSource.CopyMode_MakeSourceFullPath(pRelFileName)), lang.FILE_EXPLORER_TEXT_42_4_17, lang.FILE_EXPLORER_TEXT_42_4_18, ref pFlags.ReadSourceFileError))
                        {
                            pSource.CopyMode_AbortOperation(); pDestination.CopyMode_AbortOperation(); // Prerusim operacie
                            if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                            Decryptor.Close();
                            pSource.CopyMode_CloseStreamForRead(SourceStream, false); // Uzatvorim subor
                            pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                            if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                            return -1; // Prerusenie
                        }
                        switch (pFlags.ReadSourceFileError)
                        {
                            case IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP:
                            case IConfirmationFlags.OPEN_SOURCE_ERROR_SKIP_ALL:
                                {
                                    pSource.CopyMode_AbortOperation(); pDestination.CopyMode_AbortOperation(); // Prerusim operacie
                                    if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                                    Decryptor.Close();
                                    pSource.CopyMode_CloseStreamForRead(SourceStream, false); // Uzatvorim subor
                                    pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                                    if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                    return 1;
                                }
                        }
                    }
                    if (C == 0) break; // Koniec citania?

                    for (int i = 0; i < C; i++) CRC += Buffer[i]; // Aktualizujem CRC

                    while (true)
                    {
                        if (pProgressForm != null)
                        {
                            if (pProgressForm.WaitForTerminate.BoolValue)
                            {
                                pSource.CopyMode_AbortOperation(); pDestination.CopyMode_AbortOperation(); // Prerusim operacie
                                if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                                Decryptor.Close();
                                pSource.CopyMode_CloseStreamForRead(SourceStream, false); // Uzatvorim subor
                                pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                                if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor
                                return -1; // Prerusenie
                            }
                        }

                        R = pDestination.CopyMode_WriteFile(Buffer, 0, C);
                        if (R == 0) break;

                        pSource.CopyMode_AbortOperation(); pDestination.CopyMode_AbortOperation(); // Prerusim operacie
                        if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                        Decryptor.Close();
                        pSource.CopyMode_CloseStreamForRead(SourceStream, false); // Uzatvorim subor
                        pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                        if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor

                        if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_42_4_19, pDestination.CopyMode_MakeSourceFullPath(OutFN)), lang.FILE_EXPLORER_TEXT_42_4_20, lang.FILE_EXPLORER_TEXT_42_4_21, ref pFlags.WriteDestinationFileError))
                        {
                            return -1; // Test ukoncenia
                        }
                        return 1;
                    }
                    if (pProgressForm != null) pProgressForm.AddTransferredDataSize(C); // Zaradim data
                    ToRead -= C;
                }

                R = Decryptor.ReadData(Buffer, 4); // Nacitam CRC
                uint CRC1 = BitConverter.ToUInt32(Buffer, 0); // Ziskam CRC zo suboru
                if ((R != 4) || (CRC != CRC1)) // Chyba citania alebo nesedi CRC?
                {
                    pSource.CopyMode_AbortOperation(); pDestination.CopyMode_AbortOperation(); // Prerusim operacie
                    if (pProgressForm != null) pProgressForm.AddTransferredDataSize(-1); // Koniec prenosu
                    Decryptor.Close();
                    pSource.CopyMode_CloseStreamForRead(SourceStream, false); // Uzatvorim subor
                    pDestination.CopyMode_CloseWriteFile(true); // Uzatvorim subor
                    if (pProgressForm != null) pProgressForm.AddFile(true); // Zaradim subor

                    if (pFlags.CheckIntegritySourceFileError != IConfirmationFlags.CHECK_INTEGRITY_SOURCE_ERROR_SKIP_ALL)
                    {
                        if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_42_4_22, pDestination.CopyMode_MakeSourceFullPath(OutFN)), lang.FILE_EXPLORER_TEXT_42_4_23, lang.FILE_EXPLORER_TEXT_42_4_24, ref pFlags.CheckIntegritySourceFileError))
                        {
                            return -1; // Test ukoncenia
                        }
                        return 1;
                    }
                }

                Decryptor.Close();
            }
            pDestination.CopyMode_CloseWriteFile(false); // Uzatvorim subory
            pSource.CopyMode_CloseStreamForRead(SourceStream, false);
            if (pProgressForm != null) pProgressForm.AddFile(false);
            return 0; // Vsetko OK
        }

        /// <summary>Spustenie procesu premenovania multi poloziek</summary>
        /// <param name="pData">data</param>
        /// <param name="pProgressForm">progress formular</param>
        /// <returns>true / false</returns>
        public static bool Run_MultiRenameItems(IMultiRenameData_Str pData, IFileExplorer_ProgressForm_MultiRename pProgressForm = null)
        {
            INodeList SourceList = null;
            int Flag = 0;

            int C = pData.SourceFileNames.Count;
            for (int i = 0; i < C; i++) // Prejdem vsetky zaznamy
            {
                if ((pProgressForm != null) && (pProgressForm.WaitForTerminate.BoolValue)) // Prerusenie?
                {
                    if (SourceList != null) SourceList.Dispose();
                    return false;
                }
                string FN = pData.SourceFileNames[i];
                string RelFN = IFileSystem.ExtractName(FN);
                string NewFN = pData.DestinationFileNames[i];
                string Parent = IFileSystem.ExtractPath(FN);

                if ((SourceList == null) || ((SourceList != null) && (SourceList.CurrentPath != Parent))) // Budem vytvarat list?
                {
                    if (SourceList != null) SourceList.Dispose();
                    SourceList = INodeList.CreateNodeList(Parent);
                }

                if (SourceList == null) continue; // Nie je list?
                if (!SourceList.CanRename) continue;

                int R;
                string S1 = "", S2 = "";
                while (true)
                {
                    int R1 = SourceList.GetItemType(RelFN); // Ziskam typ
                    switch (R1)
                    {
                        case IFileSystem.OBJECT_TYPE_FILE:
                            {
                                S1 = lang.FILE_EXPLORER_TEXT_47_3_1;
                                S2 = lang.FILE_EXPLORER_TEXT_47_3_4;
                                R = SourceList.RenameFile(FN, NewFN);
                                if ((R == 0) && (pProgressForm != null)) pProgressForm.AddFile();
                            } break;
                        case IFileSystem.OBJECT_TYPE_DIRECTORY:
                            {
                                S1 = lang.FILE_EXPLORER_TEXT_47_3_2;
                                S2 = lang.FILE_EXPLORER_TEXT_47_3_5;
                                R = SourceList.RenameFolder(FN, NewFN);
                                if ((R == 0) && (pProgressForm != null)) pProgressForm.AddDir();
                            } break;
                        default: continue;
                    }
                    if (R == 0) break; // OK?
                    if (Flag == 2) break; // Preskocit vzdy?

                    if (pProgressForm != null) // Je progress formular?
                    {
                        // Opytam sa co robit
                        if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(S1, FN), lang.FILE_EXPLORER_TEXT_47_3_3, S2, ref Flag))
                        {
                            SourceList.Dispose(); SourceList = null;
                            return false;
                        }
                    }
                    if (Flag > 0) break; // Preskocenie?
                }
            }

            return true; // Vsetko OK
        }

        /// <summary>Spustenie procesu vytvorenie suboru zo schranky</summary>
        /// <param name="pType">typ</param>
        /// <param name="pOutputName">nazov suboru</param>
        /// <param name="pProgressForm">progress formular</param>
        /// <param name="pDestinationConnectionProvider">cielove spojenie</param>
        /// <returns>true / false</returns>
        public static bool Run_CreateFileFromClipboard(int pType, string pOutputName, IFileExplorer_ProgressForm_CreateFileFromClipboard pProgressForm = null, int pDestinationConnectionProvider = 0)
        {
            IConfirmationFlags Flags = new IConfirmationFlags();
            INodeList DestList = INodeList.CreateNodeList(IFileSystem.ExtractPath(pOutputName));
            if (DestList == null) return false; // Chyba

            using (DestList) // Pouzijem zoznam
            {
                DestList.BeginDestinationCopyMode();
                if (DestList.FState != 3) return false; // Nepodarila sa inicializacia?

                bool IsFolder;
                string RelFN = DestList.CopyMode_MakeRelative(pOutputName, out IsFolder);
                if (string.IsNullOrEmpty(RelFN)) return false; // Chyba

                while (true)
                {
                    int R = DestList.CopyMode_CreateWriteFile(RelFN, IWin32.FILE_ATTRIBUTE_NORMAL, DateTime.Now, Flags.ForceOverwriteDestinationFile, Flags.ForceOverwriteReadOnlyDestinationFile, Flags.ForceOverwriteSystemDestinationFile, Flags.ForceOverwriteSystemDestinationFile, true); // Vytvorim cielovy subor
                    if (R == 0) break; // OK..

                    switch (R)
                    {
                        case IFileSystem.FS_ERROR_FILE_EXISTS:
                            {
                                if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_45_9, pOutputName), lang.FILE_EXPLORER_TEXT_45_10, lang.FILE_EXPLORER_TEXT_45_11, ref Flags.OverwriteDestinationFile)) return false;
                            } break;
                        case IFileSystem.FS_ERROR_READ_ONLY_ATTRIBUTE:
                            {
                                if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_45_12, pOutputName), lang.FILE_EXPLORER_TEXT_45_10, lang.FILE_EXPLORER_TEXT_45_11, ref Flags.OverwriteReadOnlyDestinationFile)) return false;
                            } break;
                        case IFileSystem.FS_ERROR_SYSTEM_ATTRIBUTE:
                        case IFileSystem.FS_ERROR_HIDDEN_ATTRIBUTE:
                            {
                                if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_45_12, pOutputName), lang.FILE_EXPLORER_TEXT_45_10, lang.FILE_EXPLORER_TEXT_45_11, ref Flags.OverwriteSystemDestinationFile)) return false;
                            } break;
                        default:
                            {
                                if (!pProgressForm.ShowEditor_ChooseFromList(string.Format(lang.FILE_EXPLORER_TEXT_45_14, pOutputName), lang.FILE_EXPLORER_TEXT_45_15, lang.FILE_EXPLORER_TEXT_45_16, ref Flags.CreateDestinationFileError)) return false;
                            } break;
                    }
                }

                switch (pType)
                {
                    case ICore.FILE_TYPE_BMP:
                    case ICore.FILE_TYPE_JPG:
                    case ICore.FILE_TYPE_PNG:
                        {
                            System.IO.MemoryStream MS = new System.IO.MemoryStream(); // Vytvorim memory stream
                            using (MS)
                            {
                                try
                                {
                                    System.Drawing.Image Img = System.Windows.Forms.Clipboard.GetImage(); // Ziskam image
                                    using (Img)
                                    {
                                        switch (pType)
                                        {
                                            case ICore.FILE_TYPE_PNG:
                                                {
                                                    System.Drawing.Imaging.ImageCodecInfo CI = ICore.GetEncoderInfo("image/png"); // Budem nastavovat JPEG
                                                    System.Drawing.Imaging.EncoderParameters P = new System.Drawing.Imaging.EncoderParameters(1);
                                                    P.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Compression, 9); // Kvalita na 80%
                                                    Img.Save(MS, CI, P); // Ulozim ako png
                                                } break;
                                            case ICore.FILE_TYPE_JPG:
                                                {
                                                    System.Drawing.Imaging.ImageCodecInfo CI = ICore.GetEncoderInfo("image/jpeg"); // Budem nastavovat JPEG
                                                    System.Drawing.Imaging.EncoderParameters P = new System.Drawing.Imaging.EncoderParameters(1);
                                                    P.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 80L); // Kvalita na 80%
                                                    Img.Save(MS, CI, P); // Ulozim ako jpeg
                                                } break;
                                            default:
                                                {
                                                    Img.Save(MS, System.Drawing.Imaging.ImageFormat.Bmp); // Ulozim ako BMP
                                                } break;
                                        }
                                    }
                                }
                                catch
                                {
                                    DestList.CopyMode_CloseWriteFile(true);
                                    return false;
                                }

                                int Readed = 0; byte[] Buffer = new byte[MAX_COPY_BUFFER_SIZE]; MS.Position = 0;
                                while (Readed < MS.Length)
                                {
                                    int C1 = (int)(MS.Length - Readed);
                                    if (C1 > MAX_COPY_BUFFER_SIZE) C1 = MAX_COPY_BUFFER_SIZE; // Ziskam dlzku

                                    MS.Read(Buffer, 0, C1); // Nacitam data

                                    while (true)
                                    {
                                        if (DestList.CopyMode_WriteFile(Buffer, 0, C1) == 0) break; // Zapisem
                                    }
                                    Readed += C1;
                                }
                            }

                        } break;
                    case ICore.FILE_TYPE_TXT:
                    case ICore.FILE_TYPE_UNICODE_TXT:
                        {
                            try
                            {
                                byte[] Data = null;
                                switch (pType)
                                {
                                    case ICore.FILE_TYPE_UNICODE_TXT:
                                        {
                                            if (System.Windows.Forms.Clipboard.ContainsText(System.Windows.Forms.TextDataFormat.UnicodeText))
                                            {
                                                Data = System.Text.Encoding.Unicode.GetBytes(System.Windows.Forms.Clipboard.GetText(System.Windows.Forms.TextDataFormat.UnicodeText));
                                            }
                                            if (Data == null)
                                            {
                                                Data = System.Text.Encoding.Default.GetBytes(System.Windows.Forms.Clipboard.GetText(System.Windows.Forms.TextDataFormat.Text));
                                                Data = System.Text.Encoding.Convert(System.Text.Encoding.Default, System.Text.Encoding.Unicode, Data);
                                            }
                                        } break;
                                    default:
                                        {
                                            if (System.Windows.Forms.Clipboard.ContainsText(System.Windows.Forms.TextDataFormat.UnicodeText))
                                            {
                                                Data = System.Text.Encoding.Unicode.GetBytes(System.Windows.Forms.Clipboard.GetText(System.Windows.Forms.TextDataFormat.UnicodeText));
                                                Data = System.Text.Encoding.Convert(System.Text.Encoding.Unicode, System.Text.Encoding.Default, Data);
                                            }
                                            if (Data == null)
                                            {
                                                Data = System.Text.Encoding.Default.GetBytes(System.Windows.Forms.Clipboard.GetText(System.Windows.Forms.TextDataFormat.Text));
                                            }
                                        } break;
                                }

                                if (Data == null)
                                {
                                    DestList.CopyMode_CloseWriteFile(true);
                                    return false;
                                }

                                int Readed = 0;
                                while (Readed < Data.Length)
                                {
                                    int C1 = Data.Length - Readed;
                                    if (C1 > MAX_COPY_BUFFER_SIZE) C1 = MAX_COPY_BUFFER_SIZE; // Ziskam dlzku

                                    while (true)
                                    {
                                        if (DestList.CopyMode_WriteFile(Data, Readed, C1) == 0) break; // Zapisem
                                    }
                                    Readed += C1;
                                }
                            }
                            catch
                            {
                                DestList.CopyMode_CloseWriteFile(true);
                                return false;
                            }
                        } break;
                }

                DestList.CopyMode_CloseWriteFile(false);
                DestList.CloseCopyMode();
            }

            return true;
        }

        /// <summary>Vytvorenie objektu INodeList podla zadanej cesty</summary>
        /// <param name="pPath">cesta</param>
        /// <returns>objekt alebo null</returns>
        public static INodeList CreateNodeList(string pPath, int pConnectionProvider = 0)
        {
            string P, P1, P2;
            switch (IFileSystem.GetPathType(pPath, out P))
            {
                case IFileSystem.PATH_TYPE_ROOT: return new INodeList_ROOT();
                case IFileSystem.PATH_TYPE_LOCAL_FILE_SYSTEM_ROOT:
                case IFileSystem.PATH_TYPE_LOCAL_FILE_SYSTEM:
                    return new INodeList_LOCAL_ITEMS(P);
                case IFileSystem.PATH_TYPE_SAMBA_ROOT: return new INodeList_SMB_NETWORK();
                case IFileSystem.PATH_TYPE_SAMBA_COMPUTER: return new INodeList_SMB_SHARES(P);
                case IFileSystem.PATH_TYPE_SAMBA_FILE_SYSTEM:
                case IFileSystem.PATH_TYPE_SAMBA_COMPUTER_SHARE:
                    return new INodeList_SMB_ITEMS(P);
                case IFileSystem.PATH_TYPE_ARCHIVE_GZIP:
                    {
                        if (!IFileSystem.SplitFullArchivePath(P, out P1, out P2)) return null;
                        return new INodeList_GZIP(P1, P2);
                    }
                case IFileSystem.PATH_TYPE_ARCHIVE_TAR:
                    {
                        if (!IFileSystem.SplitFullArchivePath(P, out P1, out P2)) return null;
                        return new INodeList_TAR(P1, P2);
                    }
                case IFileSystem.PATH_TYPE_ARCHIVE_TGZ:
                    {
                        if (!IFileSystem.SplitFullArchivePath(P, out P1, out P2)) return null;
                        return new INodeList_TGZ(P1, P2);
                    }
                case IFileSystem.PATH_TYPE_ARCHIVE_RAR:
                    {
                        if (!IFileSystem.SplitFullArchivePath(P, out P1, out P2)) return null;
                        return new INodeList_RAR(P1, P2);
                    }
                case IFileSystem.PATH_TYPE_ARCHIVE_ZIP:
                    {
                        if (!IFileSystem.SplitFullArchivePath(P, out P1, out P2)) return null;
                        return new INodeList_ZIP(P1, P2);
                    }
                case IFileSystem.PATH_TYPE_CLOUD_ROOT: return new INodeList_CLOUD_DEVICES();
                case IFileSystem.PATH_TYPE_FTP_FILE_SYSTEM: return new INodeList_FTP(P, pConnectionProvider);
                default: return null;
            }
        }
        /// <summary>Test ci na zadanej ceste mozne hladanie</summary>
        /// <param name="pPath">cesta</param>
        /// <param name="pUseArchive">pouzit aj archivy</param>
        /// <returns>true / false</returns>
        public static bool IsSearchablePath(string pPath, bool pUseArchive = false)
        {
            INodeList L = INodeList.CreateNodeList(pPath); // Vytvorim node list
            if (L == null) return false; // Neplatne?
            
            bool B = L.SupportSearch; // Ziskam priznak moznosti hladania
            if ((B) && (!pUseArchive)) B = !L.IsArchive; // Aplikujem archiv

            L.Dispose(); L = null; // Zrusim list
            return B; // Vratim vysledok
        }
    }
}
